convert games to new providers

pull/702/head
Luke Pulverenti 11 years ago
parent 53776b332c
commit 9e0c1340fc

@ -0,0 +1,110 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Serialization;
using ServiceStack;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Api
{
/// <summary>
/// Class GetConfiguration
/// </summary>
[Route("/System/Configuration", "GET")]
[Api(("Gets application configuration"))]
public class GetConfiguration : IReturn<ServerConfiguration>
{
}
/// <summary>
/// Class UpdateConfiguration
/// </summary>
[Route("/System/Configuration", "POST")]
[Api(("Updates application configuration"))]
public class UpdateConfiguration : ServerConfiguration, IReturnVoid
{
}
[Route("/System/Configuration/MetadataOptions/Default", "GET")]
[Api(("Gets a default MetadataOptions object"))]
public class GetDefaultMetadataOptions : IReturn<MetadataOptions>
{
}
[Route("/System/Configuration/MetadataPlugins", "GET")]
[Api(("Gets all available metadata plugins"))]
public class GetMetadataPlugins : IReturn<List<MetadataPluginSummary>>
{
}
public class ConfigurationService : BaseApiService
{
/// <summary>
/// The _json serializer
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
/// The _configuration manager
/// </summary>
private readonly IServerConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
private readonly IProviderManager _providerManager;
public ConfigurationService(IJsonSerializer jsonSerializer, IServerConfigurationManager configurationManager, IFileSystem fileSystem, IProviderManager providerManager)
{
_jsonSerializer = jsonSerializer;
_configurationManager = configurationManager;
_fileSystem = fileSystem;
_providerManager = providerManager;
}
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get(GetConfiguration request)
{
var configPath = _configurationManager.ApplicationPaths.SystemConfigurationFilePath;
var dateModified = _fileSystem.GetLastWriteTimeUtc(configPath);
var cacheKey = (configPath + dateModified.Ticks).GetMD5();
return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => _configurationManager.Configuration);
}
/// <summary>
/// Posts the specified configuraiton.
/// </summary>
/// <param name="request">The request.</param>
public void Post(UpdateConfiguration request)
{
// Silly, but we need to serialize and deserialize or the XmlSerializer will write the xml with an element name of UpdateConfiguration
var json = _jsonSerializer.SerializeToString(request);
var config = _jsonSerializer.DeserializeFromString<ServerConfiguration>(json);
_configurationManager.ReplaceConfiguration(config);
}
public object Get(GetDefaultMetadataOptions request)
{
return ToOptimizedResult(new MetadataOptions());
}
public object Get(GetMetadataPlugins request)
{
return ToOptimizedResult(_providerManager.GetAllMetadataPlugins().ToList());
}
}
}

@ -72,6 +72,7 @@
</Compile>
<Compile Include="AlbumsService.cs" />
<Compile Include="BaseApiService.cs" />
<Compile Include="ConfigurationService.cs" />
<Compile Include="DefaultTheme\DefaultThemeService.cs" />
<Compile Include="DefaultTheme\Models.cs" />
<Compile Include="DisplayPreferencesService.cs" />

@ -161,7 +161,7 @@ namespace MediaBrowser.Api.Playback.Progressive
if (!string.IsNullOrEmpty(contentFeatures))
{
responseHeaders["ContentFeatures.DLNA.ORG"] = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
responseHeaders["contentFeatures.dlna.org"] = (contentFeatures + orgOp + orgCi + dlnaflags).Trim(';');
}
foreach (var item in responseHeaders)

@ -1,14 +1,6 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Serialization;
using MediaBrowser.Controller;
using MediaBrowser.Model.System;
using ServiceStack;
using System;
using System.IO;
using System.Threading.Tasks;
namespace MediaBrowser.Api
@ -38,71 +30,25 @@ namespace MediaBrowser.Api
{
}
/// <summary>
/// Class GetConfiguration
/// </summary>
[Route("/System/Configuration", "GET")]
[Api(("Gets application configuration"))]
public class GetConfiguration : IReturn<ServerConfiguration>
{
}
/// <summary>
/// Class UpdateConfiguration
/// </summary>
[Route("/System/Configuration", "POST")]
[Api(("Updates application configuration"))]
public class UpdateConfiguration : ServerConfiguration, IReturnVoid
{
}
/// <summary>
/// Class SystemInfoService
/// </summary>
public class SystemService : BaseApiService
{
/// <summary>
/// The _json serializer
/// </summary>
private readonly IJsonSerializer _jsonSerializer;
/// <summary>
/// The _app host
/// </summary>
private readonly IServerApplicationHost _appHost;
/// <summary>
/// The _configuration manager
/// </summary>
private readonly IServerConfigurationManager _configurationManager;
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="SystemService" /> class.
/// </summary>
/// <param name="jsonSerializer">The json serializer.</param>
/// <param name="appHost">The app host.</param>
/// <param name="configurationManager">The configuration manager.</param>
/// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
public SystemService(IJsonSerializer jsonSerializer, IServerApplicationHost appHost, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
: base()
public SystemService(IServerApplicationHost appHost)
{
if (jsonSerializer == null)
{
throw new ArgumentNullException("jsonSerializer");
}
if (appHost == null)
{
throw new ArgumentNullException("appHost");
}
_appHost = appHost;
_configurationManager = configurationManager;
_fileSystem = fileSystem;
_jsonSerializer = jsonSerializer;
}
/// <summary>
@ -117,22 +63,6 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result);
}
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get(GetConfiguration request)
{
var configPath = _configurationManager.ApplicationPaths.SystemConfigurationFilePath;
var dateModified = _fileSystem.GetLastWriteTimeUtc(configPath);
var cacheKey = (configPath + dateModified.Ticks).GetMD5();
return ToOptimizedResultUsingCache(cacheKey, dateModified, null, () => _configurationManager.Configuration);
}
/// <summary>
/// Posts the specified request.
/// </summary>
@ -159,19 +89,5 @@ namespace MediaBrowser.Api
});
}
/// <summary>
/// Posts the specified configuraiton.
/// </summary>
/// <param name="request">The request.</param>
public void Post(UpdateConfiguration request)
{
// Silly, but we need to serialize and deserialize or the XmlSerializer will write the xml with an element name of UpdateConfiguration
var json = _jsonSerializer.SerializeToString(request);
var config = _jsonSerializer.DeserializeFromString<ServerConfiguration>(json);
_configurationManager.ReplaceConfiguration(config);
}
}
}

@ -34,7 +34,6 @@ namespace MediaBrowser.Controller.Entities
Images = new Dictionary<ImageType, string>();
ProviderIds = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
LockedFields = new List<MetadataFields>();
ImageSources = new List<ImageSourceInfo>();
}
/// <summary>
@ -474,12 +473,6 @@ namespace MediaBrowser.Controller.Entities
/// <value>The backdrop image paths.</value>
public List<string> BackdropImagePaths { get; set; }
/// <summary>
/// Gets or sets the backdrop image sources.
/// </summary>
/// <value>The backdrop image sources.</value>
public List<ImageSourceInfo> ImageSources { get; set; }
/// <summary>
/// Gets or sets the official rating.
/// </summary>
@ -1458,8 +1451,6 @@ namespace MediaBrowser.Controller.Entities
BackdropImagePaths.Remove(file);
RemoveImageSourceForPath(file);
// Delete the source file
DeleteImagePath(file);
}
@ -1567,88 +1558,12 @@ namespace MediaBrowser.Controller.Entities
{
BackdropImagePaths.Remove(path);
RemoveImageSourceForPath(path);
changed = true;
}
return changed;
}
/// <summary>
/// Adds the image source.
/// </summary>
/// <param name="path">The path.</param>
/// <param name="url">The URL.</param>
public void AddImageSource(string path, string url)
{
RemoveImageSourceForPath(path);
var pathMd5 = path.ToLower().GetMD5();
ImageSources.Add(new ImageSourceInfo
{
ImagePathMD5 = pathMd5,
ImageUrlMD5 = url.ToLower().GetMD5()
});
}
/// <summary>
/// Gets the image source info.
/// </summary>
/// <param name="path">The path.</param>
/// <returns>ImageSourceInfo.</returns>
public ImageSourceInfo GetImageSourceInfo(string path)
{
if (ImageSources.Count == 0)
{
return null;
}
var pathMd5 = path.ToLower().GetMD5();
return ImageSources.FirstOrDefault(i => i.ImagePathMD5 == pathMd5);
}
/// <summary>
/// Removes the image source for path.
/// </summary>
/// <param name="path">The path.</param>
public void RemoveImageSourceForPath(string path)
{
if (ImageSources.Count == 0)
{
return;
}
var pathMd5 = path.ToLower().GetMD5();
// Remove existing
foreach (var entry in ImageSources
.Where(i => i.ImagePathMD5 == pathMd5)
.ToList())
{
ImageSources.Remove(entry);
}
}
/// <summary>
/// Determines whether [contains image with source URL] [the specified URL].
/// </summary>
/// <param name="url">The URL.</param>
/// <returns><c>true</c> if [contains image with source URL] [the specified URL]; otherwise, <c>false</c>.</returns>
public bool ContainsImageWithSourceUrl(string url)
{
if (ImageSources.Count == 0)
{
return false;
}
var md5 = url.ToLower().GetMD5();
return ImageSources.Any(i => i.ImageUrlMD5 == md5);
}
/// <summary>
/// Validates the screenshots.
/// </summary>

@ -99,13 +99,6 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value>The backdrop image paths.</value>
List<string> BackdropImagePaths { get; set; }
/// <summary>
/// Determines whether [contains image with source URL] [the specified URL].
/// </summary>
/// <param name="url">The URL.</param>
/// <returns><c>true</c> if [contains image with source URL] [the specified URL]; otherwise, <c>false</c>.</returns>
bool ContainsImageWithSourceUrl(string url);
}
public static class HasImagesExtensions

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

@ -165,7 +165,6 @@ namespace MediaBrowser.Controller.Library
/// <param name="prescanTasks">The prescan tasks.</param>
/// <param name="postscanTasks">The postscan tasks.</param>
/// <param name="peoplePrescanTasks">The people prescan tasks.</param>
/// <param name="savers">The savers.</param>
void AddParts(IEnumerable<IResolverIgnoreRule> rules,
IEnumerable<IVirtualFolderCreator> pluginFolders,
IEnumerable<IItemResolver> resolvers,
@ -173,8 +172,7 @@ namespace MediaBrowser.Controller.Library
IEnumerable<IBaseItemComparer> itemComparers,
IEnumerable<ILibraryPrescanTask> prescanTasks,
IEnumerable<ILibraryPostScanTask> postscanTasks,
IEnumerable<IPeoplePrescanTask> peoplePrescanTasks,
IEnumerable<IMetadataSaver> savers);
IEnumerable<IPeoplePrescanTask> peoplePrescanTasks);
/// <summary>
/// Sorts the specified items.
@ -300,14 +298,6 @@ namespace MediaBrowser.Controller.Library
/// <returns>System.String.</returns>
string FindCollectionType(BaseItem item);
/// <summary>
/// Saves the metadata.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns>Task.</returns>
Task SaveMetadata(BaseItem item, ItemUpdateType updateType);
/// <summary>
/// Gets all artists.
/// </summary>

@ -1,4 +1,4 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using System.Threading;
namespace MediaBrowser.Controller.Library
@ -8,20 +8,26 @@ namespace MediaBrowser.Controller.Library
/// </summary>
public interface IMetadataSaver
{
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
string Name { get; }
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
bool IsEnabledFor(BaseItem item, ItemUpdateType updateType);
bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType);
/// <summary>
/// Gets the save path.
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
string GetSavePath(BaseItem item);
string GetSavePath(IHasMetadata item);
/// <summary>
/// Saves the specified item.
@ -29,6 +35,6 @@ namespace MediaBrowser.Controller.Library
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
void Save(BaseItem item, CancellationToken cancellationToken);
void Save(IHasMetadata item, CancellationToken cancellationToken);
}
}

@ -143,6 +143,7 @@
<Compile Include="Notifications\NotificationUpdateEventArgs.cs" />
<Compile Include="Persistence\IFileOrganizationRepository.cs" />
<Compile Include="Persistence\MediaStreamQuery.cs" />
<Compile Include="Providers\ICustomMetadataProvider.cs" />
<Compile Include="Providers\IDynamicInfoProvider.cs" />
<Compile Include="Providers\IHasMetadata.cs" />
<Compile Include="Providers\IImageProvider.cs" />

@ -0,0 +1,15 @@
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public interface ICustomMetadataProvider : IMetadataProvider
{
}
public interface ICustomMetadataProvider<TItemType> : IMetadataProvider<TItemType>, ICustomMetadataProvider
where TItemType : IHasMetadata
{
Task FetchAsync(TItemType item, CancellationToken cancellationToken);
}
}

@ -27,5 +27,11 @@ namespace MediaBrowser.Controller.Providers
/// </summary>
/// <value>The date last saved.</value>
DateTime DateLastSaved { get; set; }
/// <summary>
/// Determines whether [is save local metadata enabled].
/// </summary>
/// <returns><c>true</c> if [is save local metadata enabled]; otherwise, <c>false</c>.</returns>
bool IsSaveLocalMetadataEnabled();
}
}

@ -1,17 +1,10 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Controller.Providers
{
public interface IMetadataService
{
/// <summary>
/// Adds the parts.
/// </summary>
/// <param name="providers">The providers.</param>
void AddParts(IEnumerable<IMetadataProvider> providers);
/// <summary>
/// Determines whether this instance can refresh the specified item.
/// </summary>
@ -23,10 +16,10 @@ namespace MediaBrowser.Controller.Providers
/// Refreshes the metadata.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="options">The options.</param>
/// <param name="refreshOptions">The options.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken);
Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken);
/// <summary>
/// Gets the order.

@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers;
using System.Collections.Generic;
@ -64,7 +65,9 @@ namespace MediaBrowser.Controller.Providers
/// <param name="imageProviders">The image providers.</param>
/// <param name="metadataServices">The metadata services.</param>
/// <param name="metadataProviders">The metadata providers.</param>
void AddParts(IEnumerable<BaseMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders);
/// <param name="savers">The savers.</param>
void AddParts(IEnumerable<BaseMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders,
IEnumerable<IMetadataSaver> savers);
/// <summary>
/// Gets the available remote images.
@ -82,5 +85,19 @@ namespace MediaBrowser.Controller.Providers
/// <param name="item">The item.</param>
/// <returns>IEnumerable{ImageProviderInfo}.</returns>
IEnumerable<ImageProviderInfo> GetImageProviderInfo(IHasImages item);
/// <summary>
/// Gets all metadata plugins.
/// </summary>
/// <returns>IEnumerable{MetadataPlugin}.</returns>
IEnumerable<MetadataPluginSummary> GetAllMetadataPlugins();
/// <summary>
/// Saves the metadata.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns>Task.</returns>
Task SaveMetadata(IHasMetadata item, ItemUpdateType updateType);
}
}

@ -51,4 +51,22 @@ namespace MediaBrowser.Controller.Providers
/// <value>The artist music brainz identifier.</value>
public string ArtistMusicBrainzId { get; set; }
}
public class GameId : ItemId
{
/// <summary>
/// Gets or sets the game system.
/// </summary>
/// <value>The game system.</value>
public string GameSystem { get; set; }
}
public class GameSystemId : ItemId
{
/// <summary>
/// Gets or sets the path.
/// </summary>
/// <value>The path.</value>
public string Path { get; set; }
}
}

@ -74,15 +74,21 @@
<Compile Include="..\MediaBrowser.Model\ApiClient\ServerEventArgs.cs">
<Link>ApiClient\ServerEventArgs.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\AutoOrganize.cs">
<Link>Configuration\AutoOrganize.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\BaseApplicationConfiguration.cs">
<Link>Configuration\BaseApplicationConfiguration.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\ImageDownloadOptions.cs">
<Link>Configuration\ImageDownloadOptions.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\ManualLoginCategory.cs">
<Link>Configuration\ManualLoginCategory.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\MetadataOptions.cs">
<Link>Configuration\MetadataOptions.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\MetadataPlugin.cs">
<Link>Configuration\MetadataPlugin.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\ServerConfiguration.cs">
<Link>Configuration\ServerConfiguration.cs</Link>
</Compile>

@ -61,15 +61,21 @@
<Compile Include="..\MediaBrowser.Model\ApiClient\ServerEventArgs.cs">
<Link>ApiClient\ServerEventArgs.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\AutoOrganize.cs">
<Link>Configuration\AutoOrganize.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\BaseApplicationConfiguration.cs">
<Link>Configuration\BaseApplicationConfiguration.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\ImageDownloadOptions.cs">
<Link>Configuration\ImageDownloadOptions.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\ManualLoginCategory.cs">
<Link>Configuration\ManualLoginCategory.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\MetadataOptions.cs">
<Link>Configuration\MetadataOptions.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\MetadataPlugin.cs">
<Link>Configuration\MetadataPlugin.cs</Link>
</Compile>
<Compile Include="..\MediaBrowser.Model\Configuration\ServerConfiguration.cs">
<Link>Configuration\ServerConfiguration.cs</Link>
</Compile>

@ -0,0 +1,36 @@

namespace MediaBrowser.Model.Configuration
{
public class TvFileOrganizationOptions
{
public bool IsEnabled { get; set; }
public int MinFileSizeMb { get; set; }
public string[] LeftOverFileExtensionsToDelete { get; set; }
public string[] WatchLocations { get; set; }
public string SeasonFolderPattern { get; set; }
public string SeasonZeroFolderName { get; set; }
public string EpisodeNamePattern { get; set; }
public string MultiEpisodeNamePattern { get; set; }
public bool OverwriteExistingEpisodes { get; set; }
public bool DeleteEmptyFolders { get; set; }
public TvFileOrganizationOptions()
{
MinFileSizeMb = 50;
LeftOverFileExtensionsToDelete = new string[] { };
WatchLocations = new string[] { };
EpisodeNamePattern = "%sn - %sx%0e - %en.%ext";
MultiEpisodeNamePattern = "%sn - %sx%0e-x%0ed - %en.%ext";
SeasonFolderPattern = "Season %s";
SeasonZeroFolderName = "Season 0";
}
}
}

@ -1,81 +0,0 @@

namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// Class ImageDownloadOptions
/// </summary>
public class ImageDownloadOptions
{
/// <summary>
/// Download Art Image
/// </summary>
/// <value><c>true</c> if art; otherwise, <c>false</c>.</value>
public bool Art { get; set; }
/// <summary>
/// Download Logo Image
/// </summary>
/// <value><c>true</c> if logo; otherwise, <c>false</c>.</value>
public bool Logo { get; set; }
/// <summary>
/// Download Primary Image
/// </summary>
/// <value><c>true</c> if primary; otherwise, <c>false</c>.</value>
public bool Primary { get; set; }
/// <summary>
/// Download Backdrop Images
/// </summary>
/// <value><c>true</c> if backdrops; otherwise, <c>false</c>.</value>
public bool Backdrops { get; set; }
/// <summary>
/// Download Disc Image
/// </summary>
/// <value><c>true</c> if disc; otherwise, <c>false</c>.</value>
public bool Disc { get; set; }
/// <summary>
/// Download Thumb Image
/// </summary>
/// <value><c>true</c> if thumb; otherwise, <c>false</c>.</value>
public bool Thumb { get; set; }
/// <summary>
/// Download Banner Image
/// </summary>
/// <value><c>true</c> if banner; otherwise, <c>false</c>.</value>
public bool Banner { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="ImageDownloadOptions"/> class.
/// </summary>
public ImageDownloadOptions()
{
Art = true;
Logo = true;
Primary = true;
Backdrops = true;
Disc = true;
Thumb = true;
Banner = true;
}
}
/// <summary>
/// Class MetadataOptions.
/// </summary>
public class MetadataOptions
{
public int MaxBackdrops { get; set; }
public int MinBackdropWidth { get; set; }
public MetadataOptions()
{
MaxBackdrops = 3;
MinBackdropWidth = 1280;
}
}
}

@ -0,0 +1,89 @@
using MediaBrowser.Model.Entities;
using System;
using System.Collections.Generic;
using System.Linq;
namespace MediaBrowser.Model.Configuration
{
/// <summary>
/// Class MetadataOptions.
/// </summary>
public class MetadataOptions
{
public string ItemType { get; set; }
public ImageOption[] ImageOptions { get; set; }
public string[] DisabledMetadataSavers { get; set; }
public MetadataOptions()
: this(3, 1280)
{
}
public MetadataOptions(int backdropLimit, int minBackdropWidth)
{
var imageOptions = new List<ImageOption>
{
new ImageOption
{
Limit = backdropLimit,
MinWidth = minBackdropWidth,
Type = ImageType.Backdrop
}
};
ImageOptions = imageOptions.ToArray();
DisabledMetadataSavers = new string[] { };
}
public int GetLimit(ImageType type)
{
var option = ImageOptions.FirstOrDefault(i => i.Type == type);
return option == null ? 1 : option.Limit;
}
public int GetMinWidth(ImageType type)
{
var option = ImageOptions.FirstOrDefault(i => i.Type == type);
return option == null ? 0 : option.MinWidth;
}
public bool IsEnabled(ImageType type)
{
return GetLimit(type) > 0;
}
public bool IsMetadataSaverEnabled(string name)
{
return !DisabledMetadataSavers.Contains(name, StringComparer.OrdinalIgnoreCase);
}
}
public class ImageOption
{
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public ImageType Type { get; set; }
/// <summary>
/// Gets or sets the limit.
/// </summary>
/// <value>The limit.</value>
public int Limit { get; set; }
/// <summary>
/// Gets or sets the minimum width.
/// </summary>
/// <value>The minimum width.</value>
public int MinWidth { get; set; }
public ImageOption()
{
Limit = 1;
}
}
}

@ -0,0 +1,60 @@
using MediaBrowser.Model.Entities;
using System.Collections.Generic;
namespace MediaBrowser.Model.Configuration
{
public class MetadataPlugin
{
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
public string Name { get; set; }
/// <summary>
/// Gets or sets the type.
/// </summary>
/// <value>The type.</value>
public MetadataPluginType Type { get; set; }
}
public class MetadataPluginSummary
{
/// <summary>
/// Gets or sets the type of the item.
/// </summary>
/// <value>The type of the item.</value>
public string ItemType { get; set; }
/// <summary>
/// Gets or sets the plugins.
/// </summary>
/// <value>The plugins.</value>
public List<MetadataPlugin> Plugins { get; set; }
/// <summary>
/// Gets or sets the supported image types.
/// </summary>
/// <value>The supported image types.</value>
public List<ImageType> SupportedImageTypes { get; set; }
public MetadataPluginSummary()
{
SupportedImageTypes = new List<ImageType>();
Plugins = new List<MetadataPlugin>();
}
}
/// <summary>
/// Enum MetadataPluginType
/// </summary>
public enum MetadataPluginType
{
LocalImageProvider,
ImageFetcher,
ImageSaver,
LocalMetadataProvider,
MetadataFetcher,
MetadataSaver
}
}

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Model.Weather;
using System;
@ -87,31 +88,6 @@ namespace MediaBrowser.Model.Configuration
/// <value>The metadata country code.</value>
public string MetadataCountryCode { get; set; }
/// <summary>
/// Options for specific art to download for movies.
/// </summary>
public ImageDownloadOptions DownloadMovieImages { get; set; }
/// <summary>
/// Options for specific art to download for Series.
/// </summary>
public ImageDownloadOptions DownloadSeriesImages { get; set; }
/// <summary>
/// Options for specific art to download for Seasons.
/// </summary>
public ImageDownloadOptions DownloadSeasonImages { get; set; }
/// <summary>
/// Options for specific art to download for MusicArtists.
/// </summary>
public ImageDownloadOptions DownloadMusicArtistImages { get; set; }
/// <summary>
/// Options for specific art to download for MusicAlbums.
/// </summary>
public ImageDownloadOptions DownloadMusicAlbumImages { get; set; }
/// <summary>
/// Characters to be replaced with a ' ' in strings to create a sort name
/// </summary>
@ -215,11 +191,7 @@ namespace MediaBrowser.Model.Configuration
public bool EnableEpisodeChapterImageExtraction { get; set; }
public bool EnableOtherVideoChapterImageExtraction { get; set; }
public MetadataOptions MovieOptions { get; set; }
public MetadataOptions TvOptions { get; set; }
public MetadataOptions MusicOptions { get; set; }
public MetadataOptions GameOptions { get; set; }
public MetadataOptions BookOptions { get; set; }
public MetadataOptions[] MetadataOptions { get; set; }
public bool EnableDebugEncodingLogging { get; set; }
public string TranscodingTempPath { get; set; }
@ -267,14 +239,6 @@ namespace MediaBrowser.Model.Configuration
MetadataRefreshDays = 30;
PreferredMetadataLanguage = "en";
MetadataCountryCode = "US";
DownloadMovieImages = new ImageDownloadOptions();
DownloadSeriesImages = new ImageDownloadOptions();
DownloadSeasonImages = new ImageDownloadOptions
{
Backdrops = false
};
DownloadMusicArtistImages = new ImageDownloadOptions();
DownloadMusicAlbumImages = new ImageDownloadOptions();
SortReplaceCharacters = new[] { ".", "+", "%" };
SortRemoveCharacters = new[] { ",", "&", "-", "{", "}", "'" };
@ -282,26 +246,26 @@ namespace MediaBrowser.Model.Configuration
SeasonZeroDisplayName = "Specials";
MovieOptions = new MetadataOptions();
TvOptions = new MetadataOptions();
LiveTvOptions = new LiveTvOptions();
MusicOptions = new MetadataOptions()
{
MaxBackdrops = 1
};
TvFileOrganizationOptions = new TvFileOrganizationOptions();
GameOptions = new MetadataOptions();
EnableRealtimeMonitor = true;
BookOptions = new MetadataOptions
var options = new List<MetadataOptions>
{
MaxBackdrops = 1
new MetadataOptions(1, 1280) {ItemType = "Book"},
new MetadataOptions(1, 1280) {ItemType = "MusicAlbum"},
new MetadataOptions(1, 1280) {ItemType = "MusicArtist"},
new MetadataOptions(0, 1280) {ItemType = "Season"}
};
LiveTvOptions = new LiveTvOptions();
TvFileOrganizationOptions = new TvFileOrganizationOptions();
MetadataOptions = options.ToArray();
}
EnableRealtimeMonitor = true;
public MetadataOptions GetMetadataOptions(string type)
{
return MetadataOptions.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase));
}
}
@ -324,39 +288,6 @@ namespace MediaBrowser.Model.Configuration
public int? GuideDays { get; set; }
}
public class TvFileOrganizationOptions
{
public bool IsEnabled { get; set; }
public int MinFileSizeMb { get; set; }
public string[] LeftOverFileExtensionsToDelete { get; set; }
public string[] WatchLocations { get; set; }
public string SeasonFolderPattern { get; set; }
public string SeasonZeroFolderName { get; set; }
public string EpisodeNamePattern { get; set; }
public string MultiEpisodeNamePattern { get; set; }
public bool OverwriteExistingEpisodes { get; set; }
public bool DeleteEmptyFolders { get; set; }
public TvFileOrganizationOptions()
{
MinFileSizeMb = 50;
LeftOverFileExtensionsToDelete = new string[] {};
WatchLocations = new string[] { };
EpisodeNamePattern = "%sn - %sx%0e - %en.%ext";
MultiEpisodeNamePattern = "%sn - %sx%0e-x%0ed - %en.%ext";
SeasonFolderPattern = "Season %s";
SeasonZeroFolderName = "Season 0";
}
}
public class PathSubstitution
{
public string From { get; set; }

@ -58,8 +58,11 @@
<Compile Include="ApiClient\ApiClientExtensions.cs" />
<Compile Include="ApiClient\IServerEvents.cs" />
<Compile Include="ApiClient\ServerEventArgs.cs" />
<Compile Include="Configuration\AutoOrganize.cs" />
<Compile Include="Configuration\BaseApplicationConfiguration.cs" />
<Compile Include="Configuration\ManualLoginCategory.cs" />
<Compile Include="Configuration\MetadataPlugin.cs" />
<Compile Include="Configuration\MetadataOptions.cs" />
<Compile Include="Configuration\ServerConfiguration.cs" />
<Compile Include="Drawing\ImageOutputFormat.cs" />
<Compile Include="Dto\BaseItemPerson.cs" />
@ -124,7 +127,6 @@
<Compile Include="Session\MessageCommand.cs" />
<Compile Include="Session\PlayRequest.cs" />
<Compile Include="Session\PlaystateCommand.cs" />
<Compile Include="Configuration\ImageDownloadOptions.cs" />
<Compile Include="Logging\ILogManager.cs" />
<Compile Include="MediaInfo\BlurayDiscInfo.cs" />
<Compile Include="Entities\ChapterInfo.cs" />

@ -17,18 +17,18 @@ namespace MediaBrowser.Providers
FileSystem = fileSystem;
}
protected abstract string GetXmlPath(string path);
protected abstract FileInfo GetXmlFile(string path);
public bool HasChanged(IHasMetadata item, DateTime date)
{
var path = GetXmlPath(item.Path);
var file = GetXmlFile(item.Path);
return FileSystem.GetLastWriteTimeUtc(path) > date;
return FileSystem.GetLastWriteTimeUtc(file) > date;
}
public bool HasLocalMetadata(IHasMetadata item)
{
return File.Exists(GetXmlPath(item.Path));
return GetXmlFile(item.Path).Exists;
}
}
}

@ -1,9 +1,12 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Localization;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -15,13 +18,13 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.BoxSets
{
public class BoxSetMetadataService : ConcreteMetadataService<BoxSet, ItemId>
public class BoxSetMetadataService : MetadataService<BoxSet, ItemId>
{
private readonly ILibraryManager _libraryManager;
private readonly ILocalizationManager _iLocalizationManager;
public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager, ILocalizationManager iLocalizationManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public BoxSetMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager, ILocalizationManager iLocalizationManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
_iLocalizationManager = iLocalizationManager;
@ -34,6 +37,7 @@ namespace MediaBrowser.Providers.BoxSets
/// <param name="target">The target.</param>
/// <param name="lockedFields">The locked fields.</param>
/// <param name="replaceData">if set to <c>true</c> [replace data].</param>
/// <param name="mergeMetadataSettings">if set to <c>true</c> [merge metadata settings].</param>
protected override void MergeData(BoxSet source, BoxSet target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);

@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.BoxSets
public async Task<MetadataResult<BoxSet>> GetMetadata(string path, CancellationToken cancellationToken)
{
path = GetXmlPath(path);
path = GetXmlFile(path).FullName;
var result = new MetadataResult<BoxSet>();
@ -51,12 +51,12 @@ namespace MediaBrowser.Providers.BoxSets
public string Name
{
get { return "Media Browser Xml"; }
get { return "Media Browser xml"; }
}
protected override string GetXmlPath(string path)
protected override FileInfo GetXmlFile(string path)
{
return Path.Combine(path, "collection.xml");
return new FileInfo(Path.Combine(path, "collection.xml"));
}
}
}

@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.GameGenres
public static string ProviderName
{
get { return "Media Browser"; }
get { return "Media Browser Images"; }
}
public bool Supports(IHasImages item)

@ -1,7 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +14,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.GameGenres
{
public class GameGenreMetadataService : ConcreteMetadataService<GameGenre, ItemId>
public class GameGenreMetadataService : MetadataService<GameGenre, ItemId>
{
private readonly ILibraryManager _libraryManager;
public GameGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public GameGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -0,0 +1,59 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.Games
{
public class GameMetadataService : MetadataService<Game, GameId>
{
private readonly ILibraryManager _libraryManager;
public GameMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}
/// <summary>
/// Merges the specified source.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="target">The target.</param>
/// <param name="lockedFields">The locked fields.</param>
/// <param name="replaceData">if set to <c>true</c> [replace data].</param>
/// <param name="mergeMetadataSettings">if set to <c>true</c> [merge metadata settings].</param>
protected override void MergeData(Game source, Game target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
if (replaceData || string.IsNullOrEmpty(target.GameSystem))
{
target.GameSystem = source.GameSystem;
}
}
protected override Task SaveItem(Game item, ItemUpdateType reason, CancellationToken cancellationToken)
{
return _libraryManager.UpdateItem(item, reason, cancellationToken);
}
protected override GameId GetId(Game item)
{
var id = base.GetId(item);
id.GameSystem = item.GameSystem;
return id;
}
}
}

@ -1,93 +0,0 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Savers;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.Games
{
public class GameProviderFromXml : BaseMetadataProvider
{
private readonly IFileSystem _fileSystem;
/// <summary>
///
/// </summary>
/// <param name="logManager"></param>
/// <param name="configurationManager"></param>
public GameProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
: base(logManager, configurationManager)
{
_fileSystem = fileSystem;
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public override bool Supports(BaseItem item)
{
return item is Game;
}
protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
{
var savePath = GameXmlSaver.GetGameSavePath(item);
var xml = item.ResolveArgs.GetMetaFileByPath(savePath) ?? new FileInfo(savePath);
if (!xml.Exists)
{
return false;
}
return _fileSystem.GetLastWriteTimeUtc(xml) > item.DateLastSaved;
}
/// <summary>
///
/// </summary>
/// <param name="item"></param>
/// <param name="force"></param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
{
var game = (Game)item;
cancellationToken.ThrowIfCancellationRequested();
var metaFile = GameXmlSaver.GetGameSavePath(game);
if (File.Exists(metaFile))
{
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
new GameXmlParser(Logger).Fetch(game, metaFile, cancellationToken);
}
finally
{
XmlParsingResourcePool.Release();
}
}
SetLastRefreshed(game, DateTime.UtcNow, providerInfo);
return true;
}
/// <summary>
///
/// </summary>
public override MetadataProviderPriority Priority
{
get { return MetadataProviderPriority.Second; }
}
}
}

@ -0,0 +1,59 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.Games
{
public class GameSystemMetadataService : MetadataService<GameSystem, GameSystemId>
{
private readonly ILibraryManager _libraryManager;
public GameSystemMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}
/// <summary>
/// Merges the specified source.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="target">The target.</param>
/// <param name="lockedFields">The locked fields.</param>
/// <param name="replaceData">if set to <c>true</c> [replace data].</param>
/// <param name="mergeMetadataSettings">if set to <c>true</c> [merge metadata settings].</param>
protected override void MergeData(GameSystem source, GameSystem target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
if (replaceData || string.IsNullOrEmpty(target.GameSystemName))
{
target.GameSystemName = source.GameSystemName;
}
}
protected override Task SaveItem(GameSystem item, ItemUpdateType reason, CancellationToken cancellationToken)
{
return _libraryManager.UpdateItem(item, reason, cancellationToken);
}
protected override GameSystemId GetId(GameSystem item)
{
var id = base.GetId(item);
id.Path = item.Path;
return id;
}
}
}

@ -1,92 +0,0 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.Games
{
public class GameSystemProviderFromXml : BaseMetadataProvider
{
private readonly IFileSystem _fileSystem;
public GameSystemProviderFromXml(ILogManager logManager, IServerConfigurationManager configurationManager, IFileSystem fileSystem)
: base(logManager, configurationManager)
{
_fileSystem = fileSystem;
}
/// <summary>
/// Supportses the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
public override bool Supports(BaseItem item)
{
return item is GameSystem && item.LocationType == LocationType.FileSystem;
}
/// <summary>
/// Gets the priority.
/// </summary>
/// <value>The priority.</value>
public override MetadataProviderPriority Priority
{
get { return MetadataProviderPriority.Second; }
}
private const string XmlFileName = "gamesystem.xml";
protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
{
var xml = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
if (xml == null)
{
return false;
}
return _fileSystem.GetLastWriteTimeUtc(xml) > item.DateLastSaved;
}
/// <summary>
/// Fetches metadata and returns true or false indicating if any work that requires persistence was done
/// </summary>
/// <param name="item">The item.</param>
/// <param name="force">if set to <c>true</c> [force].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{System.Boolean}.</returns>
public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
var metadataFile = item.ResolveArgs.GetMetaFileByPath(Path.Combine(item.MetaLocation, XmlFileName));
if (metadataFile != null)
{
var path = metadataFile.FullName;
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
new BaseItemXmlParser<GameSystem>(Logger).Fetch((GameSystem)item, path, cancellationToken);
}
finally
{
XmlParsingResourcePool.Release();
}
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
return true;
}
return false;
}
}
}

@ -0,0 +1,63 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
namespace MediaBrowser.Providers.Games
{
public class GameSystemXmlParser : BaseItemXmlParser<GameSystem>
{
public GameSystemXmlParser(ILogger logger)
: base(logger)
{
}
public Task FetchAsync(GameSystem item, string metadataFile, CancellationToken cancellationToken)
{
Fetch(item, metadataFile, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
return Task.FromResult(true);
}
/// <summary>
/// Fetches the data from XML node.
/// </summary>
/// <param name="reader">The reader.</param>
/// <param name="item">The item.</param>
protected override void FetchDataFromXmlNode(XmlReader reader, GameSystem item)
{
switch (reader.Name)
{
case "GameSystem":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
item.GameSystemName = val;
}
break;
}
case "GamesDbId":
{
var val = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(val))
{
item.SetProviderId(MetadataProviders.Gamesdb, val);
}
break;
}
default:
base.FetchDataFromXmlNode(reader, item);
break;
}
}
}
}

@ -0,0 +1,59 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.Games
{
public class GameSystemXmlProvider : BaseXmlProvider, ILocalMetadataProvider<GameSystem>
{
private readonly ILogger _logger;
public GameSystemXmlProvider(IFileSystem fileSystem, ILogger logger)
: base(fileSystem)
{
_logger = logger;
}
public async Task<MetadataResult<GameSystem>> GetMetadata(string path, CancellationToken cancellationToken)
{
path = GetXmlFile(path).FullName;
var result = new MetadataResult<GameSystem>();
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
var item = new GameSystem();
new GameSystemXmlParser(_logger).Fetch(item, path, cancellationToken);
result.HasMetadata = true;
result.Item = item;
}
catch (FileNotFoundException)
{
result.HasMetadata = false;
}
finally
{
XmlParsingResourcePool.Release();
}
return result;
}
public string Name
{
get { return "Media Browser xml"; }
}
protected override FileInfo GetXmlFile(string path)
{
return new FileInfo(Path.Combine(path, "gamesystem.xml"));
}
}
}

@ -14,7 +14,6 @@ namespace MediaBrowser.Providers.Games
/// </summary>
public class GameXmlParser : BaseItemXmlParser<Game>
{
private Task _chaptersTask = null;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
public GameXmlParser(ILogger logger)
@ -22,18 +21,13 @@ namespace MediaBrowser.Providers.Games
{
}
public async Task FetchAsync(Game item, string metadataFile, CancellationToken cancellationToken)
public Task FetchAsync(Game item, string metadataFile, CancellationToken cancellationToken)
{
_chaptersTask = null;
Fetch(item, metadataFile, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
if (_chaptersTask != null)
{
await _chaptersTask.ConfigureAwait(false);
}
return Task.FromResult(true);
}
/// <summary>

@ -0,0 +1,74 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.Games
{
public class GameXmlProvider : BaseXmlProvider, ILocalMetadataProvider<Game>
{
private readonly ILogger _logger;
public GameXmlProvider(IFileSystem fileSystem, ILogger logger)
: base(fileSystem)
{
_logger = logger;
}
public async Task<MetadataResult<Game>> GetMetadata(string path, CancellationToken cancellationToken)
{
path = GetXmlFile(path).FullName;
var result = new MetadataResult<Game>();
await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
var item = new Game();
new GameXmlParser(_logger).Fetch(item, path, cancellationToken);
result.HasMetadata = true;
result.Item = item;
}
catch (FileNotFoundException)
{
result.HasMetadata = false;
}
finally
{
XmlParsingResourcePool.Release();
}
return result;
}
public string Name
{
get { return "Media Browser xml"; }
}
protected override FileInfo GetXmlFile(string path)
{
var fileInfo = FileSystem.GetFileSystemInfo(path);
var directoryInfo = fileInfo as DirectoryInfo;
if (directoryInfo == null)
{
directoryInfo = new DirectoryInfo(Path.GetDirectoryName(path));
}
var directoryPath = directoryInfo.FullName;
var specificFile = Path.Combine(directoryPath, Path.GetFileNameWithoutExtension(path) + ".xml");
var file = new FileInfo(specificFile);
return file.Exists ? file : new FileInfo(Path.Combine(directoryPath, "game.xml"));
}
}
}

@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.Genres
public static string ProviderName
{
get { return "Media Browser"; }
get { return "Media Browser Images"; }
}
public bool Supports(IHasImages item)

@ -1,7 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +14,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Genres
{
public class GenreMetadataService : ConcreteMetadataService<Genre, ItemId>
public class GenreMetadataService : MetadataService<Genre, ItemId>
{
private readonly ILibraryManager _libraryManager;
public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -1,7 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +14,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.LiveTv
{
public class ChannelMetadataService : ConcreteMetadataService<LiveTvChannel, ItemId>
public class ChannelMetadataService : MetadataService<LiveTvChannel, ItemId>
{
private readonly ILibraryManager _libraryManager;
public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public ChannelMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.LiveTv
public async Task<MetadataResult<LiveTvChannel>> GetMetadata(string path, CancellationToken cancellationToken)
{
path = GetXmlPath(path);
path = GetXmlFile(path).FullName;
var result = new MetadataResult<LiveTvChannel>();
@ -48,12 +48,12 @@ namespace MediaBrowser.Providers.LiveTv
public string Name
{
get { return "Media Browser Xml"; }
get { return "Media Browser xml"; }
}
protected override string GetXmlPath(string path)
protected override FileInfo GetXmlFile(string path)
{
return Path.Combine(path, "channel.xml");
return new FileInfo(Path.Combine(path, "channel.xml"));
}
}
}

@ -1,7 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +14,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.LiveTv
{
public class ProgramMetadataService : ConcreteMetadataService<LiveTvProgram, ItemId>
public class ProgramMetadataService : MetadataService<LiveTvProgram, ItemId>
{
private readonly ILibraryManager _libraryManager;
public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public ProgramMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -1,21 +0,0 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
namespace MediaBrowser.Providers.Manager
{
public abstract class ConcreteMetadataService<TItemType, TIdType> : MetadataService<TItemType, TIdType>
where TItemType : IHasMetadata, new()
where TIdType : ItemId, new()
{
protected ConcreteMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
{
}
protected override TItemType CreateNew()
{
return new TItemType();
}
}
}

@ -309,15 +309,6 @@ namespace MediaBrowser.Providers.Manager
{
item.BackdropImagePaths.Add(path);
}
if (string.IsNullOrEmpty(sourceUrl))
{
item.RemoveImageSourceForPath(path);
}
else
{
item.AddImageSource(path, sourceUrl);
}
break;
default:
item.SetImagePath(type, path);

@ -1,16 +1,17 @@
using System.IO;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
@ -25,11 +26,12 @@ namespace MediaBrowser.Providers.Manager
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
public ItemImageProvider(ILogger logger, IProviderManager providerManager, IServerConfigurationManager config)
public ItemImageProvider(ILogger logger, IProviderManager providerManager, IServerConfigurationManager config, IFileSystem fileSystem)
{
_logger = logger;
_providerManager = providerManager;
_config = config;
_fileSystem = fileSystem;
}
public bool ValidateImages(IHasImages item, IEnumerable<IImageProvider> providers)
@ -49,7 +51,7 @@ namespace MediaBrowser.Providers.Manager
return hasChanges;
}
public async Task<RefreshResult> RefreshImages(IHasImages item, IEnumerable<IImageProvider> imageProviders, ImageRefreshOptions options, 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 };
@ -57,16 +59,20 @@ namespace MediaBrowser.Providers.Manager
var providerIds = new List<Guid>();
// In order to avoid duplicates, only download these if there are none already
var backdropLimit = item.HasImage(ImageType.Backdrop) ? 0 : savedOptions.GetLimit(ImageType.Backdrop);
var screenshotLimit = item.HasImage(ImageType.Screenshot) ? 0 : savedOptions.GetLimit(ImageType.Screenshot);
foreach (var provider in providers.OfType<IRemoteImageProvider>())
{
await RefreshFromProvider(item, provider, options, result, cancellationToken).ConfigureAwait(false);
await RefreshFromProvider(item, provider, refreshOptions, savedOptions, backdropLimit, screenshotLimit, result, cancellationToken).ConfigureAwait(false);
providerIds.Add(provider.GetType().FullName.GetMD5());
}
foreach (var provider in providers.OfType<IDynamicImageProvider>())
{
await RefreshFromProvider(item, provider, result, cancellationToken).ConfigureAwait(false);
await RefreshFromProvider(item, provider, savedOptions, result, cancellationToken).ConfigureAwait(false);
providerIds.Add(provider.GetType().FullName.GetMD5());
}
@ -81,10 +87,11 @@ namespace MediaBrowser.Providers.Manager
/// </summary>
/// <param name="item">The item.</param>
/// <param name="provider">The provider.</param>
/// <param name="savedOptions">The saved options.</param>
/// <param name="result">The result.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
private async Task RefreshFromProvider(IHasImages item, IDynamicImageProvider provider, RefreshResult result, CancellationToken cancellationToken)
private async Task RefreshFromProvider(IHasImages item, IDynamicImageProvider provider, MetadataOptions savedOptions, RefreshResult result, CancellationToken cancellationToken)
{
_logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name);
@ -94,7 +101,7 @@ namespace MediaBrowser.Providers.Manager
foreach (var imageType in images)
{
if (!item.HasImage(imageType))
if (!item.HasImage(imageType) && savedOptions.IsEnabled(imageType))
{
var response = await provider.GetImage(item, imageType, cancellationToken).ConfigureAwait(false);
@ -152,17 +159,20 @@ namespace MediaBrowser.Providers.Manager
/// <summary>
/// Determines if an item already contains the given images
/// </summary>
/// <param name="item"></param>
/// <param name="images"></param>
/// <returns></returns>
private bool ContainsImages(IHasImages item, List<ImageType> images)
/// <param name="item">The item.</param>
/// <param name="images">The images.</param>
/// <param name="savedOptions">The saved options.</param>
/// <param name="backdropLimit">The backdrop limit.</param>
/// <param name="screenshotLimit">The screenshot limit.</param>
/// <returns><c>true</c> if the specified item contains images; otherwise, <c>false</c>.</returns>
private bool ContainsImages(IHasImages item, List<ImageType> images, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit)
{
if (_singularImages.Any(i => images.Contains(i) && !item.HasImage(i)))
if (_singularImages.Any(i => images.Contains(i) && !item.HasImage(i) && savedOptions.GetLimit(i) > 0))
{
return false;
}
if (images.Contains(ImageType.Backdrop) && item.BackdropImagePaths.Count < GetMaxBackdropCount(item))
if (images.Contains(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit)
{
return false;
}
@ -172,7 +182,7 @@ namespace MediaBrowser.Providers.Manager
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
if (hasScreenshots.ScreenshotImagePaths.Count < GetMaxBackdropCount(item))
if (hasScreenshots.ScreenshotImagePaths.Count < screenshotLimit)
{
return false;
}
@ -187,16 +197,18 @@ namespace MediaBrowser.Providers.Manager
/// </summary>
/// <param name="item">The item.</param>
/// <param name="provider">The provider.</param>
/// <param name="options">The options.</param>
/// <param name="refreshOptions">The refresh options.</param>
/// <param name="savedOptions">The saved options.</param>
/// <param name="backdropLimit">The backdrop limit.</param>
/// <param name="screenshotLimit">The screenshot limit.</param>
/// <param name="result">The result.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
private async Task RefreshFromProvider(IHasImages item, IRemoteImageProvider provider, ImageRefreshOptions options, RefreshResult result, CancellationToken cancellationToken)
private async Task RefreshFromProvider(IHasImages item, IRemoteImageProvider provider, ImageRefreshOptions refreshOptions, MetadataOptions savedOptions, int backdropLimit, int screenshotLimit, RefreshResult result, CancellationToken cancellationToken)
{
try
{
// TODO: Also factor in IsConfiguredToDownloadImage
if (ContainsImages(item, provider.GetSupportedImages(item).ToList()))
if (ContainsImages(item, provider.GetSupportedImages(item).ToList(), savedOptions, backdropLimit, screenshotLimit))
{
return;
}
@ -208,18 +220,18 @@ namespace MediaBrowser.Providers.Manager
foreach (var type in _singularImages)
{
if (IsConfiguredToDownloadImage(item, type) && !item.HasImage(type))
if (savedOptions.IsEnabled(type) && !item.HasImage(type))
{
await DownloadImage(item, provider, result, list, type, cancellationToken).ConfigureAwait(false);
}
}
await DownloadBackdrops(item, provider, result, list, cancellationToken).ConfigureAwait(false);
await DownloadBackdrops(item, backdropLimit, provider, result, list, cancellationToken).ConfigureAwait(false);
var hasScreenshots = item as IHasScreenshots;
if (hasScreenshots != null)
{
await DownloadScreenshots(hasScreenshots, provider, result, list, cancellationToken).ConfigureAwait(false);
await DownloadScreenshots(hasScreenshots, screenshotLimit, provider, result, list, cancellationToken).ConfigureAwait(false);
}
}
catch (OperationCanceledException)
@ -342,25 +354,19 @@ namespace MediaBrowser.Providers.Manager
}
}
private async Task DownloadBackdrops(IHasImages item, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, CancellationToken cancellationToken)
private async Task DownloadBackdrops(IHasImages item, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, CancellationToken cancellationToken)
{
const ImageType imageType = ImageType.Backdrop;
var maxCount = GetMaxBackdropCount(item);
foreach (var image in images.Where(i => i.Type == imageType))
{
if (item.BackdropImagePaths.Count >= maxCount)
if (item.BackdropImagePaths.Count >= limit)
{
break;
}
var url = image.Url;
if (item.ContainsImageWithSourceUrl(url))
{
continue;
}
try
{
var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false);
@ -381,25 +387,19 @@ namespace MediaBrowser.Providers.Manager
}
}
private async Task DownloadScreenshots(IHasScreenshots item, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, CancellationToken cancellationToken)
private async Task DownloadScreenshots(IHasScreenshots item, int limit, IRemoteImageProvider provider, RefreshResult result, IEnumerable<RemoteImageInfo> images, CancellationToken cancellationToken)
{
const ImageType imageType = ImageType.Screenshot;
var maxCount = GetMaxScreenshotCount(item);
foreach (var image in images.Where(i => i.Type == imageType))
{
if (item.ScreenshotImagePaths.Count >= maxCount)
if (item.ScreenshotImagePaths.Count >= limit)
{
break;
}
var url = image.Url;
if (item.ContainsImageWithSourceUrl(url))
{
continue;
}
try
{
var response = await provider.GetImageResponse(url, cancellationToken).ConfigureAwait(false);
@ -419,20 +419,5 @@ namespace MediaBrowser.Providers.Manager
}
}
}
private bool IsConfiguredToDownloadImage(IHasImages item, ImageType type)
{
return true;
}
private int GetMaxBackdropCount(IHasImages item)
{
return 1;
}
private int GetMaxScreenshotCount(IHasScreenshots item)
{
return 1;
}
}
}

@ -1,7 +1,9 @@
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
@ -13,32 +15,22 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Manager
{
public abstract class MetadataService<TItemType, TIdType> : IMetadataService
where TItemType : IHasMetadata
where TItemType : IHasMetadata, new()
where TIdType : ItemId, new()
{
protected readonly IServerConfigurationManager ServerConfigurationManager;
protected readonly ILogger Logger;
protected readonly IProviderManager ProviderManager;
private readonly IProviderRepository _providerRepo;
protected readonly IProviderRepository ProviderRepo;
protected readonly IFileSystem FileSystem;
private IMetadataProvider<TItemType>[] _providers = { };
protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo)
protected MetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem)
{
ServerConfigurationManager = serverConfigurationManager;
Logger = logger;
ProviderManager = providerManager;
_providerRepo = providerRepo;
}
/// <summary>
/// Adds the parts.
/// </summary>
/// <param name="providers">The providers.</param>
public void AddParts(IEnumerable<IMetadataProvider> providers)
{
_providers = providers.OfType<IMetadataProvider<TItemType>>()
.ToArray();
ProviderRepo = providerRepo;
FileSystem = fileSystem;
}
/// <summary>
@ -48,7 +40,7 @@ namespace MediaBrowser.Providers.Manager
/// <returns>Task.</returns>
protected Task SaveProviderResult(MetadataStatus result)
{
return _providerRepo.SaveMetadataStatus(result, CancellationToken.None);
return ProviderRepo.SaveMetadataStatus(result, CancellationToken.None);
}
/// <summary>
@ -58,20 +50,22 @@ namespace MediaBrowser.Providers.Manager
/// <returns>ProviderResult.</returns>
protected MetadataStatus GetLastResult(Guid itemId)
{
return _providerRepo.GetMetadataStatus(itemId) ?? new MetadataStatus { ItemId = itemId };
return ProviderRepo.GetMetadataStatus(itemId) ?? new MetadataStatus { ItemId = itemId };
}
public async Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken)
public async Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions refreshOptions, CancellationToken cancellationToken)
{
var itemOfType = (TItemType)item;
var config = GetMetadataOptions(itemOfType);
var updateType = ItemUpdateType.Unspecified;
var lastResult = GetLastResult(item.Id);
var refreshResult = lastResult;
refreshResult.LastErrorMessage = string.Empty;
refreshResult.LastStatus = ProviderRefreshStatus.Success;
var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager);
var itemImageProvider = new ItemImageProvider(Logger, ProviderManager, ServerConfigurationManager, FileSystem);
var localImagesFailed = false;
var allImageProviders = ((ProviderManager)ProviderManager).GetImageProviders(item).ToList();
@ -93,13 +87,13 @@ namespace MediaBrowser.Providers.Manager
}
// Next run metadata providers
if (options.MetadataRefreshMode != MetadataRefreshMode.None)
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
{
var providers = GetProviders(item, lastResult.DateLastMetadataRefresh.HasValue, options).ToList();
var providers = GetProviders(item, lastResult.DateLastMetadataRefresh.HasValue, refreshOptions).ToList();
if (providers.Count > 0)
{
var result = await RefreshWithProviders(itemOfType, options, providers, cancellationToken).ConfigureAwait(false);
var result = await RefreshWithProviders(itemOfType, refreshOptions, providers, cancellationToken).ConfigureAwait(false);
updateType = updateType | result.UpdateType;
refreshResult.AddStatus(result.Status, result.ErrorMessage);
@ -109,13 +103,13 @@ namespace MediaBrowser.Providers.Manager
}
// Next run remote image providers, but only if local image providers didn't throw an exception
if (!localImagesFailed && options.ImageRefreshMode != ImageRefreshMode.ValidationOnly)
if (!localImagesFailed && refreshOptions.ImageRefreshMode != ImageRefreshMode.ValidationOnly)
{
var providers = GetNonLocalImageProviders(item, allImageProviders, lastResult.DateLastImagesRefresh.HasValue, options).ToList();
var providers = GetNonLocalImageProviders(item, allImageProviders, lastResult.DateLastImagesRefresh.HasValue, refreshOptions).ToList();
if (providers.Count > 0)
{
var result = await itemImageProvider.RefreshImages(itemOfType, providers, options, cancellationToken).ConfigureAwait(false);
var result = await itemImageProvider.RefreshImages(itemOfType, providers, refreshOptions, config, cancellationToken).ConfigureAwait(false);
updateType = updateType | result.UpdateType;
refreshResult.AddStatus(result.Status, result.ErrorMessage);
@ -128,7 +122,7 @@ namespace MediaBrowser.Providers.Manager
var providersHadChanges = updateType > ItemUpdateType.Unspecified;
if (options.ForceSave || providersHadChanges)
if (refreshOptions.ForceSave || providersHadChanges)
{
if (string.IsNullOrEmpty(item.Name))
{
@ -145,6 +139,15 @@ namespace MediaBrowser.Providers.Manager
}
}
private readonly MetadataOptions _defaultOptions = new MetadataOptions();
protected MetadataOptions GetMetadataOptions(TItemType item)
{
var type = item.GetType().Name;
return ServerConfigurationManager.Configuration.MetadataOptions
.FirstOrDefault(i => string.Equals(i.ItemType, type, StringComparison.OrdinalIgnoreCase)) ??
_defaultOptions;
}
/// <summary>
/// Afters the metadata refresh.
/// </summary>
@ -292,10 +295,35 @@ namespace MediaBrowser.Providers.Manager
MergeData(temp, item, item.LockedFields, true, true);
}
foreach (var provider in providers.OfType<ICustomMetadataProvider<TItemType>>())
{
Logger.Debug("Running {0} for {1}", provider.GetType().Name, item.Path ?? item.Name);
try
{
await provider.FetchAsync(item, cancellationToken).ConfigureAwait(false);
refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataDownload;
}
catch (OperationCanceledException)
{
throw;
}
catch (Exception ex)
{
refreshResult.Status = ProviderRefreshStatus.CompletedWithErrors;
refreshResult.ErrorMessage = ex.Message;
Logger.ErrorException("Error in {0}", ex, provider.Name);
}
}
return refreshResult;
}
protected abstract TItemType CreateNew();
protected virtual TItemType CreateNew()
{
return new TItemType();
}
private async Task ExecuteRemoteProviders(TItemType item, TItemType temp, IEnumerable<IRemoteMetadataProvider<TItemType>> providers, RefreshResult refreshResult, CancellationToken cancellationToken)
{

@ -2,14 +2,17 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -58,6 +61,7 @@ namespace MediaBrowser.Providers.Manager
private IMetadataService[] _metadataServices = { };
private IMetadataProvider[] _metadataProviders = { };
private IEnumerable<IMetadataSaver> _savers;
/// <summary>
/// Initializes a new instance of the <see cref="ProviderManager" /> class.
@ -85,7 +89,8 @@ namespace MediaBrowser.Providers.Manager
/// <param name="imageProviders">The image providers.</param>
/// <param name="metadataServices">The metadata services.</param>
/// <param name="metadataProviders">The metadata providers.</param>
public void AddParts(IEnumerable<BaseMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders)
/// <param name="metadataSavers">The metadata savers.</param>
public void AddParts(IEnumerable<BaseMetadataProvider> providers, IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders, IEnumerable<IMetadataSaver> metadataSavers)
{
MetadataProviders = providers.OrderBy(e => e.Priority).ToArray();
@ -93,6 +98,7 @@ namespace MediaBrowser.Providers.Manager
_metadataServices = metadataServices.OrderBy(i => i.Order).ToArray();
_metadataProviders = metadataProviders.ToArray();
_savers = metadataSavers.ToArray();
}
public Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken)
@ -479,9 +485,15 @@ namespace MediaBrowser.Providers.Manager
public IEnumerable<IMetadataProvider<T>> GetMetadataProviders<T>(IHasMetadata item)
where T : IHasMetadata
{
return GetMetadataProvidersInternal<T>(item, false);
}
private IEnumerable<IMetadataProvider<T>> GetMetadataProvidersInternal<T>(IHasMetadata item, bool includeDisabled)
where T : IHasMetadata
{
return _metadataProviders.OfType<IMetadataProvider<T>>()
.Where(i => CanRefresh(i, item))
.Where(i => CanRefresh(i, item, includeDisabled))
.OrderBy(i => GetOrder(item, i));
}
@ -495,10 +507,11 @@ namespace MediaBrowser.Providers.Manager
/// </summary>
/// <param name="provider">The provider.</param>
/// <param name="item">The item.</param>
/// <param name="includeDisabled">if set to <c>true</c> [include disabled].</param>
/// <returns><c>true</c> if this instance can refresh the specified provider; otherwise, <c>false</c>.</returns>
protected bool CanRefresh(IMetadataProvider provider, IHasMetadata item)
private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, bool includeDisabled)
{
if (!ConfigurationManager.Configuration.EnableInternetProviders && provider is IRemoteMetadataProvider)
if (!includeDisabled && !ConfigurationManager.Configuration.EnableInternetProviders && provider is IRemoteMetadataProvider)
{
return false;
}
@ -546,5 +559,148 @@ namespace MediaBrowser.Providers.Manager
return hasOrder.Order;
}
public IEnumerable<MetadataPluginSummary> GetAllMetadataPlugins()
{
var list = new List<MetadataPluginSummary>();
list.Add(GetPluginSummary<Game>());
list.Add(GetPluginSummary<GameSystem>());
list.Add(GetPluginSummary<Movie>());
list.Add(GetPluginSummary<Trailer>());
list.Add(GetPluginSummary<BoxSet>());
list.Add(GetPluginSummary<Book>());
list.Add(GetPluginSummary<Series>());
list.Add(GetPluginSummary<Season>());
list.Add(GetPluginSummary<Episode>());
list.Add(GetPluginSummary<Person>());
list.Add(GetPluginSummary<MusicAlbum>());
list.Add(GetPluginSummary<MusicArtist>());
list.Add(GetPluginSummary<Audio>());
list.Add(GetPluginSummary<Genre>());
list.Add(GetPluginSummary<Studio>());
list.Add(GetPluginSummary<GameGenre>());
list.Add(GetPluginSummary<MusicGenre>());
return list;
}
private MetadataPluginSummary GetPluginSummary<T>()
where T : BaseItem, new()
{
// Give it a dummy path just so that it looks like a file system item
var dummy = new T()
{
Path = "C:\\",
// Dummy this up to fool the local trailer check
Parent = new Folder()
};
var summary = new MetadataPluginSummary
{
ItemType = typeof(T).Name
};
var imageProviders = GetImageProviders(dummy).ToList();
AddMetadataPlugins(summary.Plugins, dummy);
AddImagePlugins(summary.Plugins, dummy, imageProviders);
summary.SupportedImageTypes = imageProviders.OfType<IRemoteImageProvider>()
.SelectMany(i => i.GetSupportedImages(dummy))
.Distinct()
.ToList();
return summary;
}
private void AddMetadataPlugins<T>(List<MetadataPlugin> list, T item)
where T : IHasMetadata
{
var providers = GetMetadataProvidersInternal<T>(item, true).ToList();
// Locals
list.AddRange(providers.Where(i => (i is ILocalMetadataProvider)).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.LocalMetadataProvider
}));
// Fetchers
list.AddRange(providers.Where(i => !(i is ILocalMetadataProvider)).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.MetadataFetcher
}));
// Savers
list.AddRange(_savers.Where(i => i.IsEnabledFor(item, ItemUpdateType.MetadataEdit)).OrderBy(i => i.Name).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.MetadataSaver
}));
}
private void AddImagePlugins<T>(List<MetadataPlugin> list, T item, List<IImageProvider> imageProviders)
where T : IHasImages
{
// Locals
list.AddRange(imageProviders.Where(i => (i is ILocalImageProvider)).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.LocalImageProvider
}));
// Fetchers
list.AddRange(imageProviders.Where(i => !(i is ILocalImageProvider)).Select(i => new MetadataPlugin
{
Name = i.Name,
Type = MetadataPluginType.ImageFetcher
}));
}
private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
/// <summary>
/// Saves the metadata.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns>Task.</returns>
public async Task SaveMetadata(IHasMetadata item, ItemUpdateType updateType)
{
var locationType = item.LocationType;
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
{
throw new ArgumentException("Only file-system based items can save metadata.");
}
foreach (var saver in _savers.Where(i => i.IsEnabledFor(item, updateType)))
{
var path = saver.GetSavePath(item);
var semaphore = _fileLocks.GetOrAdd(path, key => new SemaphoreSlim(1, 1));
await semaphore.WaitAsync().ConfigureAwait(false);
try
{
_libraryMonitor.ReportFileSystemChangeBeginning(path);
saver.Save(item, CancellationToken.None);
}
catch (Exception ex)
{
_logger.ErrorException("Error in metadata saver", ex);
}
finally
{
_libraryMonitor.ReportFileSystemChangeComplete(path, false);
semaphore.Release();
}
}
}
}
}

@ -69,11 +69,13 @@
<Compile Include="BoxSets\MovieDbBoxSetImageProvider.cs" />
<Compile Include="BoxSets\MovieDbBoxSetProvider.cs" />
<Compile Include="GameGenres\GameGenreMetadataService.cs" />
<Compile Include="Games\GameMetadataService.cs" />
<Compile Include="Games\GameSystemMetadataService.cs" />
<Compile Include="Games\GameSystemXmlParser.cs" />
<Compile Include="Genres\GenreMetadataService.cs" />
<Compile Include="LiveTv\ChannelMetadataService.cs" />
<Compile Include="LiveTv\ChannelXmlProvider.cs" />
<Compile Include="LiveTv\ProgramMetadataService.cs" />
<Compile Include="Manager\ConcreteMetadataService.cs" />
<Compile Include="Manager\ImageSaver.cs" />
<Compile Include="Manager\ItemImageProvider.cs" />
<Compile Include="Manager\ProviderManager.cs" />
@ -82,8 +84,8 @@
<Compile Include="CollectionFolderImageProvider.cs" />
<Compile Include="FolderProviderFromXml.cs" />
<Compile Include="Games\GameXmlParser.cs" />
<Compile Include="Games\GameProviderFromXml.cs" />
<Compile Include="Games\GameSystemProviderFromXml.cs" />
<Compile Include="Games\GameXmlProvider.cs" />
<Compile Include="Games\GameSystemXmlProvider.cs" />
<Compile Include="ImageFromMediaLocationProvider.cs" />
<Compile Include="ImagesByNameProvider.cs" />
<Compile Include="Movies\MovieDbSearch.cs" />

@ -6,6 +6,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
@ -271,50 +272,53 @@ namespace MediaBrowser.Providers.Movies
{
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadMovieImages.Primary && !item.HasImage(ImageType.Primary))
var options = ConfigurationManager.Configuration.GetMetadataOptions("Movie") ?? new MetadataOptions();
if (options.IsEnabled(ImageType.Primary) && !item.HasImage(ImageType.Primary))
{
await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadMovieImages.Logo && !item.HasImage(ImageType.Logo))
if (options.IsEnabled(ImageType.Logo) && !item.HasImage(ImageType.Logo))
{
await SaveImage(item, images, ImageType.Logo, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadMovieImages.Art && !item.HasImage(ImageType.Art))
if (options.IsEnabled(ImageType.Art) && !item.HasImage(ImageType.Art))
{
await SaveImage(item, images, ImageType.Art, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadMovieImages.Disc && !item.HasImage(ImageType.Disc))
if (options.IsEnabled(ImageType.Disc) && !item.HasImage(ImageType.Disc))
{
await SaveImage(item, images, ImageType.Disc, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadMovieImages.Banner && !item.HasImage(ImageType.Banner))
if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner))
{
await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadMovieImages.Thumb && !item.HasImage(ImageType.Thumb))
if (options.IsEnabled(ImageType.Thumb) && !item.HasImage(ImageType.Thumb))
{
await SaveImage(item, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
var backdropLimit = ConfigurationManager.Configuration.MovieOptions.MaxBackdrops;
if (ConfigurationManager.Configuration.DownloadMovieImages.Backdrops &&
var backdropLimit = options.GetLimit(ImageType.Backdrop);
if (backdropLimit > 0 &&
item.BackdropImagePaths.Count < backdropLimit)
{
foreach (var image in images.Where(i => i.Type == ImageType.Backdrop))

@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
@ -126,9 +127,11 @@ namespace MediaBrowser.Providers.Movies
return false;
}
var options = ConfigurationManager.Configuration.GetMetadataOptions("Movie") ?? new MetadataOptions();
// Don't refresh if we already have both poster and backdrop and we're not refreshing images
if (item.HasImage(ImageType.Primary) &&
item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.MovieOptions.MaxBackdrops &&
item.BackdropImagePaths.Count >= options.GetLimit(ImageType.Backdrop) &&
!item.LockedFields.Contains(MetadataFields.Images))
{
return false;
@ -205,15 +208,17 @@ namespace MediaBrowser.Providers.Movies
cancellationToken.ThrowIfCancellationRequested();
var options = ConfigurationManager.Configuration.GetMetadataOptions("Movie") ?? new MetadataOptions();
var eligibleBackdrops = images
.Where(i => i.Type == ImageType.Backdrop && i.Width.HasValue && i.Width.Value >= ConfigurationManager.Configuration.MovieOptions.MinBackdropWidth)
.Where(i => i.Type == ImageType.Backdrop && i.Width.HasValue && i.Width.Value >= options.GetMinWidth(ImageType.Backdrop))
.ToList();
var backdropLimit = ConfigurationManager.Configuration.MovieOptions.MaxBackdrops;
var backdropLimit = options.GetLimit(ImageType.Backdrop);
// backdrops - only download if earlier providers didn't find any (fanart)
if (eligibleBackdrops.Count > 0 &&
ConfigurationManager.Configuration.DownloadMovieImages.Backdrops &&
options.IsEnabled(ImageType.Backdrop) &&
item.BackdropImagePaths.Count < backdropLimit &&
!item.LockedFields.Contains(MetadataFields.Backdrops))
{
@ -221,18 +226,15 @@ namespace MediaBrowser.Providers.Movies
{
var url = eligibleBackdrops[i].Url;
if (!item.ContainsImageWithSourceUrl(url))
var img = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
{
var img = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
{
Url = url,
CancellationToken = cancellationToken
Url = url,
CancellationToken = cancellationToken
}).ConfigureAwait(false);
}).ConfigureAwait(false);
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(url), ImageType.Backdrop, null, url, cancellationToken)
.ConfigureAwait(false);
}
await _providerManager.SaveImage(item, img, MimeTypes.GetMimeType(url), ImageType.Backdrop, null, url, cancellationToken)
.ConfigureAwait(false);
if (item.BackdropImagePaths.Count >= backdropLimit)
{

@ -285,7 +285,7 @@ namespace MediaBrowser.Providers.Movies
/// <returns><c>true</c> if [has alt meta] [the specified item]; otherwise, <c>false</c>.</returns>
internal static bool HasAltMeta(BaseItem item)
{
var path = MovieXmlSaver.GetMovieSavePath(item);
var path = MovieXmlSaver.GetMovieSavePath((Video)item);
if (item.LocationType == LocationType.FileSystem)
{

@ -63,7 +63,7 @@ namespace MediaBrowser.Providers.Movies
protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
{
var savePath = MovieXmlSaver.GetMovieSavePath(item);
var savePath = MovieXmlSaver.GetMovieSavePath((Video)item);
var xml = item.ResolveArgs.GetMetaFileByPath(savePath) ?? new FileInfo(savePath);
@ -86,7 +86,9 @@ namespace MediaBrowser.Providers.Movies
{
cancellationToken.ThrowIfCancellationRequested();
var path = MovieXmlSaver.GetMovieSavePath(item);
var video = (Video)item;
var path = MovieXmlSaver.GetMovieSavePath(video);
if (File.Exists(path))
{
@ -94,8 +96,6 @@ namespace MediaBrowser.Providers.Movies
try
{
var video = (Video)item;
await new MovieXmlParser(Logger, _itemRepo).FetchAsync(video, path, cancellationToken).ConfigureAwait(false);
}
finally

@ -1,7 +1,9 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -13,12 +15,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Music
{
public class AlbumMetadataService : ConcreteMetadataService<MusicAlbum, AlbumId>
public class AlbumMetadataService : MetadataService<MusicAlbum, AlbumId>
{
private readonly ILibraryManager _libraryManager;
public AlbumMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public AlbumMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.Music
public async Task<MetadataResult<MusicAlbum>> GetMetadata(string path, CancellationToken cancellationToken)
{
path = GetXmlPath(path);
path = GetXmlFile(path).FullName;
var result = new MetadataResult<MusicAlbum>();
@ -48,12 +48,12 @@ namespace MediaBrowser.Providers.Music
public string Name
{
get { return "Media Browser Xml"; }
get { return "Media Browser xml"; }
}
protected override string GetXmlPath(string path)
protected override FileInfo GetXmlFile(string path)
{
return Path.Combine(path, "album.xml");
return new FileInfo(Path.Combine(path, "album.xml"));
}
}
}

@ -1,7 +1,9 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -13,12 +15,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Music
{
public class ArtistMetadataService : ConcreteMetadataService<MusicArtist, ItemId>
public class ArtistMetadataService : MetadataService<MusicArtist, ItemId>
{
private readonly ILibraryManager _libraryManager;
public ArtistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public ArtistMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.Music
public async Task<MetadataResult<MusicArtist>> GetMetadata(string path, CancellationToken cancellationToken)
{
path = GetXmlPath(path);
path = GetXmlFile(path).FullName;
var result = new MetadataResult<MusicArtist>();
@ -48,12 +48,12 @@ namespace MediaBrowser.Providers.Music
public string Name
{
get { return "Media Browser Xml"; }
get { return "Media Browser xml"; }
}
protected override string GetXmlPath(string path)
protected override FileInfo GetXmlFile(string path)
{
return Path.Combine(path, "artist.xml");
return new FileInfo(Path.Combine(path, "artist.xml"));
}
}
}

@ -38,7 +38,7 @@ namespace MediaBrowser.Providers.MusicGenres
public static string ProviderName
{
get { return "Media Browser"; }
get { return "Media Browser Images"; }
}
public bool Supports(IHasImages item)

@ -1,7 +1,9 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +13,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.MusicGenres
{
public class MusicGenreMetadataService : ConcreteMetadataService<MusicGenre, ItemId>
public class MusicGenreMetadataService : MetadataService<MusicGenre, ItemId>
{
private readonly ILibraryManager _libraryManager;
public MusicGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public MusicGenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -1,7 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +14,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.People
{
public class PersonMetadataService : ConcreteMetadataService<Person, ItemId>
public class PersonMetadataService : MetadataService<Person, ItemId>
{
private readonly ILibraryManager _libraryManager;
public PersonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public PersonMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -20,7 +20,7 @@ namespace MediaBrowser.Providers.People
public async Task<MetadataResult<Person>> GetMetadata(string path, CancellationToken cancellationToken)
{
path = GetXmlPath(path);
path = GetXmlFile(path).FullName;
var result = new MetadataResult<Person>();
@ -48,12 +48,12 @@ namespace MediaBrowser.Providers.People
public string Name
{
get { return "Media Browser Xml"; }
get { return "Media Browser xml"; }
}
protected override string GetXmlPath(string path)
protected override FileInfo GetXmlFile(string path)
{
return Path.Combine(path, "person.xml");
return new FileInfo(Path.Combine(path, "person.xml"));
}
}
}

@ -1,9 +1,7 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Providers.Music;
using System;
using MediaBrowser.Controller.Providers;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -20,13 +18,21 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -46,13 +52,13 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes((MusicAlbum)item, builder);
builder.Append("</Item>");
@ -66,7 +72,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "album.xml");
}

@ -2,6 +2,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Providers.Music;
using System;
using System.Collections.Generic;
@ -20,13 +21,21 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -59,13 +68,13 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes((MusicArtist)item, builder);
builder.Append("</Item>");
@ -79,7 +88,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "artist.xml");
}

@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
using MediaBrowser.Controller.Providers;
namespace MediaBrowser.Providers.Savers
{
@ -18,13 +19,21 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -44,13 +53,13 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes((BoxSet)item, builder);
builder.Append("</Item>");
@ -64,7 +73,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "collection.xml");
}

@ -1,8 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Providers.LiveTv;
using System;
using MediaBrowser.Controller.Providers;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -21,7 +19,7 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -35,19 +33,27 @@ namespace MediaBrowser.Providers.Savers
return false;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Saves the specified item.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes((LiveTvChannel)item, builder);
builder.Append("</Item>");
@ -63,7 +69,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "channel.xml");
}

@ -1,8 +1,8 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -37,6 +37,14 @@ namespace MediaBrowser.Providers.Savers
return false;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
public EpisodeXmlSaver(IServerConfigurationManager config, IItemRepository itemRepository)
@ -51,7 +59,7 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var episode = (Episode)item;
@ -112,7 +120,7 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<FirstAired>" + SecurityElement.Escape(episode.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + "</FirstAired>");
}
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes(episode, builder);
XmlSaverHelpers.AddMediaInfo(episode, builder, _itemRepository);
builder.Append("</Item>");
@ -140,7 +148,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
var filename = Path.ChangeExtension(Path.GetFileName(item.Path), ".xml");

@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -20,15 +21,25 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
if (!item.IsFolder)
var folder = item as Folder;
if (folder == null)
{
return false;
}
@ -40,7 +51,8 @@ namespace MediaBrowser.Providers.Savers
if (item.IsSaveLocalMetadataEnabled() && (wasMetadataEdited || wasMetadataDownloaded))
{
if (!(item is Series) && !(item is BoxSet) && !(item is MusicArtist) && !(item is MusicAlbum) &&
!(item is Season))
!(item is Season) &&
!(item is GameSystem))
{
return true;
}
@ -64,13 +76,13 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes((Folder)item, builder);
builder.Append("</Item>");
@ -84,7 +96,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "folder.xml");
}

@ -1,10 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Providers.Games;
using System;
using MediaBrowser.Controller.Providers;
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Text;
using System.Threading;
@ -19,13 +19,21 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -45,13 +53,20 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var gameSystem = (GameSystem)item;
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
if (!string.IsNullOrEmpty(gameSystem.GameSystemName))
{
builder.Append("<GameSystem>" + SecurityElement.Escape(gameSystem.GameSystemName) + "</GameSystem>");
}
XmlSaverHelpers.AddCommonNodes(gameSystem, builder);
builder.Append("</Item>");
@ -65,7 +80,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "gamesystem.xml");
}

@ -1,9 +1,8 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Providers.Movies;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
@ -25,13 +24,21 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -53,7 +60,7 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var builder = new StringBuilder();
@ -85,7 +92,7 @@ namespace MediaBrowser.Providers.Savers
builder.Append("<NesBoxRom>" + SecurityElement.Escape(val) + "</NesBoxRom>");
}
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes(game, builder);
builder.Append("</Item>");
@ -100,12 +107,12 @@ namespace MediaBrowser.Providers.Savers
});
}
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return GetGameSavePath(item);
return GetGameSavePath((Game)item);
}
public static string GetGameSavePath(BaseItem item)
public static string GetGameSavePath(Game item)
{
if (item.IsInMixedFolder)
{

@ -10,6 +10,7 @@ using System.IO;
using System.Security;
using System.Text;
using System.Threading;
using MediaBrowser.Controller.Providers;
namespace MediaBrowser.Providers.Savers
{
@ -27,13 +28,21 @@ namespace MediaBrowser.Providers.Savers
_itemRepository = itemRepository;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -48,9 +57,9 @@ namespace MediaBrowser.Providers.Savers
{
return !trailer.IsLocalTrailer;
}
var video = item as Video;
// Check parent for null to avoid running this against things like video backdrops
return item is Video && !(item is Episode) && item.Parent != null;
return video != null && !(item is Episode) && video.Parent != null;
}
return false;
@ -64,22 +73,24 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var video = (Video)item;
var builder = new StringBuilder();
builder.Append("<Title>");
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes(video, builder);
if (item.CommunityRating.HasValue)
if (video.CommunityRating.HasValue)
{
builder.Append("<IMDBrating>" + SecurityElement.Escape(item.CommunityRating.Value.ToString(UsCulture)) + "</IMDBrating>");
builder.Append("<IMDBrating>" + SecurityElement.Escape(video.CommunityRating.Value.ToString(UsCulture)) + "</IMDBrating>");
}
if (!string.IsNullOrEmpty(item.Overview))
if (!string.IsNullOrEmpty(video.Overview))
{
builder.Append("<Description><![CDATA[" + item.Overview + "]]></Description>");
builder.Append("<Description><![CDATA[" + video.Overview + "]]></Description>");
}
var musicVideo = item as MusicVideo;
@ -106,8 +117,6 @@ namespace MediaBrowser.Providers.Savers
}
}
var video = (Video)item;
XmlSaverHelpers.AddMediaInfo(video, builder, _itemRepository);
builder.Append("</Title>");
@ -124,12 +133,12 @@ namespace MediaBrowser.Providers.Savers
});
}
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return GetMovieSavePath(item);
return GetMovieSavePath((Video)item);
}
public static string GetMovieSavePath(BaseItem item)
public static string GetMovieSavePath(Video item)
{
if (item.IsInMixedFolder)
{

@ -1,7 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Providers.Movies;
using System;
using MediaBrowser.Controller.Providers;
using System.Collections.Generic;
using System.IO;
using System.Security;
@ -15,13 +14,21 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
public class PersonXmlSaver : IMetadataSaver
{
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -41,15 +48,15 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var person = (Person)item;
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
var person = (Person)item;
XmlSaverHelpers.AddCommonNodes(person, builder);
if (!string.IsNullOrEmpty(person.PlaceOfBirth))
{
@ -71,7 +78,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "person.xml");
}

@ -1,7 +1,7 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using System.Collections.Generic;
using System.IO;
using System.Text;
@ -18,13 +18,21 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -44,13 +52,13 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var builder = new StringBuilder();
builder.Append("<Item>");
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes((Season)item, builder);
builder.Append("</Item>");
@ -64,7 +72,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "season.xml");
}

@ -1,7 +1,7 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using System.Collections.Generic;
using System.IO;
@ -20,13 +20,21 @@ namespace MediaBrowser.Providers.Savers
_config = config;
}
public string Name
{
get
{
return "Media Browser xml";
}
}
/// <summary>
/// Determines whether [is enabled for] [the specified item].
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns><c>true</c> if [is enabled for] [the specified item]; otherwise, <c>false</c>.</returns>
public bool IsEnabledFor(BaseItem item, ItemUpdateType updateType)
public bool IsEnabledFor(IHasMetadata item, ItemUpdateType updateType)
{
var wasMetadataEdited = (updateType & ItemUpdateType.MetadataEdit) == ItemUpdateType.MetadataEdit;
var wasMetadataDownloaded = (updateType & ItemUpdateType.MetadataDownload) == ItemUpdateType.MetadataDownload;
@ -46,7 +54,7 @@ namespace MediaBrowser.Providers.Savers
/// <param name="item">The item.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
public void Save(BaseItem item, CancellationToken cancellationToken)
public void Save(IHasMetadata item, CancellationToken cancellationToken)
{
var series = (Series)item;
@ -73,7 +81,7 @@ namespace MediaBrowser.Providers.Savers
if (series.Studios.Count > 0)
{
builder.Append("<Network>" + SecurityElement.Escape(item.Studios[0]) + "</Network>");
builder.Append("<Network>" + SecurityElement.Escape(series.Studios[0]) + "</Network>");
}
if (!string.IsNullOrEmpty(series.AirTime))
@ -97,8 +105,8 @@ namespace MediaBrowser.Providers.Savers
{
builder.Append("<FirstAired>" + SecurityElement.Escape(series.PremiereDate.Value.ToLocalTime().ToString("yyyy-MM-dd")) + "</FirstAired>");
}
XmlSaverHelpers.AddCommonNodes(item, builder);
XmlSaverHelpers.AddCommonNodes(series, builder);
builder.Append("</Series>");
@ -124,7 +132,7 @@ namespace MediaBrowser.Providers.Savers
/// </summary>
/// <param name="item">The item.</param>
/// <returns>System.String.</returns>
public string GetSavePath(BaseItem item)
public string GetSavePath(IHasMetadata item)
{
return Path.Combine(item.Path, "series.xml");
}

@ -1,7 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +14,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Studios
{
public class StudioMetadataService : ConcreteMetadataService<Studio, ItemId>
public class StudioMetadataService : MetadataService<Studio, ItemId>
{
private readonly ILibraryManager _libraryManager;
public StudioMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public StudioMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_libraryManager = libraryManager;
}

@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Studios
public static string ProviderName
{
get { return "Media Browser"; }
get { return "Media Browser Images"; }
}
public bool Supports(IHasImages item)

@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
@ -121,7 +122,9 @@ namespace MediaBrowser.Providers.TV
/// <returns>Task.</returns>
private async Task FetchImages(Season season, List<RemoteImageInfo> images, CancellationToken cancellationToken)
{
if (ConfigurationManager.Configuration.DownloadSeasonImages.Thumb && !season.HasImage(ImageType.Thumb) && !season.LockedFields.Contains(MetadataFields.Images))
var options = ConfigurationManager.Configuration.GetMetadataOptions("Season") ?? new MetadataOptions();
if (options.IsEnabled(ImageType.Thumb) && !season.HasImage(ImageType.Thumb) && !season.LockedFields.Contains(MetadataFields.Images))
{
await SaveImage(season, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
}

@ -6,6 +6,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
@ -197,39 +198,41 @@ namespace MediaBrowser.Providers.TV
/// <returns>Task.</returns>
private async Task FetchFromXml(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken)
{
var options = ConfigurationManager.Configuration.GetMetadataOptions("Series") ?? new MetadataOptions();
if (!item.LockedFields.Contains(MetadataFields.Images))
{
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadSeriesImages.Primary && !item.HasImage(ImageType.Primary))
if (options.IsEnabled(ImageType.Primary) && !item.HasImage(ImageType.Primary))
{
await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadSeriesImages.Logo && !item.HasImage(ImageType.Logo))
if (options.IsEnabled(ImageType.Logo) && !item.HasImage(ImageType.Logo))
{
await SaveImage(item, images, ImageType.Logo, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadSeriesImages.Art && !item.HasImage(ImageType.Art))
if (options.IsEnabled(ImageType.Art) && !item.HasImage(ImageType.Art))
{
await SaveImage(item, images, ImageType.Art, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadSeriesImages.Thumb && !item.HasImage(ImageType.Thumb))
if (options.IsEnabled(ImageType.Thumb) && !item.HasImage(ImageType.Thumb))
{
await SaveImage(item, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
}
cancellationToken.ThrowIfCancellationRequested();
if (ConfigurationManager.Configuration.DownloadSeriesImages.Banner && !item.HasImage(ImageType.Banner))
if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner))
{
await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false);
}
@ -239,8 +242,8 @@ namespace MediaBrowser.Providers.TV
{
cancellationToken.ThrowIfCancellationRequested();
var backdropLimit = ConfigurationManager.Configuration.TvOptions.MaxBackdrops;
if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops &&
var backdropLimit = options.GetLimit(ImageType.Backdrop);
if (options.IsEnabled(ImageType.Backdrop) &&
item.BackdropImagePaths.Count < backdropLimit)
{
foreach (var image in images.Where(i => i.Type == ImageType.Backdrop))

@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
@ -149,16 +150,17 @@ namespace MediaBrowser.Providers.TV
var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualTvdbSeasonImageProvider.ProviderName).ConfigureAwait(false);
const int backdropLimit = 1;
await DownloadImages(item, images.ToList(), backdropLimit, cancellationToken).ConfigureAwait(false);
await DownloadImages(item, images.ToList(), cancellationToken).ConfigureAwait(false);
SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
return true;
}
private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, int backdropLimit, CancellationToken cancellationToken)
private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, CancellationToken cancellationToken)
{
var options = ConfigurationManager.Configuration.GetMetadataOptions("Season") ?? new MetadataOptions();
var backdropLimit = options.GetLimit(ImageType.Backdrop);
if (!item.LockedFields.Contains(MetadataFields.Images))
{
if (!item.HasImage(ImageType.Primary))
@ -166,23 +168,18 @@ namespace MediaBrowser.Providers.TV
await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
}
if (ConfigurationManager.Configuration.DownloadSeasonImages.Banner && !item.HasImage(ImageType.Banner))
if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner))
{
await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false);
}
}
if (ConfigurationManager.Configuration.DownloadSeasonImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops))
if (options.IsEnabled(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops))
{
foreach (var backdrop in images.Where(i => i.Type == ImageType.Backdrop))
{
var url = backdrop.Url;
if (item.ContainsImageWithSourceUrl(url))
{
continue;
}
await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false);
if (item.BackdropImagePaths.Count >= backdropLimit) break;

@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
@ -137,7 +138,9 @@ namespace MediaBrowser.Providers.TV
protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
{
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count >= ConfigurationManager.Configuration.TvOptions.MaxBackdrops)
var options = ConfigurationManager.Configuration.GetMetadataOptions("Series") ?? new MetadataOptions();
if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count >= options.GetLimit(ImageType.Backdrop))
{
return false;
}
@ -167,6 +170,8 @@ namespace MediaBrowser.Providers.TV
private async Task DownloadImages(BaseItem item, List<RemoteImageInfo> images, int backdropLimit, CancellationToken cancellationToken)
{
var options = ConfigurationManager.Configuration.GetMetadataOptions("Series") ?? new MetadataOptions();
if (!item.LockedFields.Contains(MetadataFields.Images))
{
if (!item.HasImage(ImageType.Primary))
@ -180,7 +185,7 @@ namespace MediaBrowser.Providers.TV
}
}
if (ConfigurationManager.Configuration.DownloadSeriesImages.Banner && !item.HasImage(ImageType.Banner))
if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner))
{
var image = images.FirstOrDefault(i => i.Type == ImageType.Banner);
@ -192,19 +197,14 @@ namespace MediaBrowser.Providers.TV
}
}
if (ConfigurationManager.Configuration.DownloadSeriesImages.Backdrops && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops))
if (options.IsEnabled(ImageType.Backdrop) && item.BackdropImagePaths.Count < backdropLimit && !item.LockedFields.Contains(MetadataFields.Backdrops))
{
foreach (var backdrop in images.Where(i => i.Type == ImageType.Backdrop &&
(!i.Width.HasValue ||
i.Width.Value >= ConfigurationManager.Configuration.TvOptions.MinBackdropWidth)))
i.Width.Value >= options.GetMinWidth(ImageType.Backdrop))))
{
var url = backdrop.Url;
if (item.ContainsImageWithSourceUrl(url))
{
continue;
}
await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false);
if (item.BackdropImagePaths.Count >= backdropLimit) break;

@ -1,7 +1,10 @@
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Providers.Manager;
@ -11,12 +14,12 @@ using System.Threading.Tasks;
namespace MediaBrowser.Providers.Users
{
public class UserMetadataService : ConcreteMetadataService<User, ItemId>
public class UserMetadataService : MetadataService<User, ItemId>
{
private readonly IUserManager _userManager;
public UserMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, ILibraryManager libraryManager, IUserManager userManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo)
public UserMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, IUserManager userManager)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
_userManager = userManager;
}
@ -28,6 +31,7 @@ namespace MediaBrowser.Providers.Users
/// <param name="target">The target.</param>
/// <param name="lockedFields">The locked fields.</param>
/// <param name="replaceData">if set to <c>true</c> [replace data].</param>
/// <param name="mergeMetadataSettings">if set to <c>true</c> [merge metadata settings].</param>
protected override void MergeData(User source, User target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
{
ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);

@ -9,6 +9,7 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.IO;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Controller.Sorting;
using MediaBrowser.Model.Configuration;
@ -135,9 +136,8 @@ namespace MediaBrowser.Server.Implementations.Library
/// <value>The by reference items.</value>
private ConcurrentDictionary<Guid, BaseItem> ByReferenceItems { get; set; }
private IEnumerable<IMetadataSaver> _savers;
private readonly Func<ILibraryMonitor> _libraryMonitorFactory;
private readonly Func<IProviderManager> _providerManagerFactory;
/// <summary>
/// The _library items cache
@ -180,7 +180,7 @@ namespace MediaBrowser.Server.Implementations.Library
/// <param name="userManager">The user manager.</param>
/// <param name="configurationManager">The configuration manager.</param>
/// <param name="userDataRepository">The user data repository.</param>
public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func<ILibraryMonitor> libraryMonitorFactory, IFileSystem fileSystem)
public LibraryManager(ILogger logger, ITaskManager taskManager, IUserManager userManager, IServerConfigurationManager configurationManager, IUserDataManager userDataRepository, Func<ILibraryMonitor> libraryMonitorFactory, IFileSystem fileSystem, Func<IProviderManager> providerManagerFactory)
{
_logger = logger;
_taskManager = taskManager;
@ -189,6 +189,7 @@ namespace MediaBrowser.Server.Implementations.Library
_userDataRepository = userDataRepository;
_libraryMonitorFactory = libraryMonitorFactory;
_fileSystem = fileSystem;
_providerManagerFactory = providerManagerFactory;
ByReferenceItems = new ConcurrentDictionary<Guid, BaseItem>();
ConfigurationManager.ConfigurationUpdated += ConfigurationUpdated;
@ -215,8 +216,7 @@ namespace MediaBrowser.Server.Implementations.Library
IEnumerable<IBaseItemComparer> itemComparers,
IEnumerable<ILibraryPrescanTask> prescanTasks,
IEnumerable<ILibraryPostScanTask> postscanTasks,
IEnumerable<IPeoplePrescanTask> peoplePrescanTasks,
IEnumerable<IMetadataSaver> savers)
IEnumerable<IPeoplePrescanTask> peoplePrescanTasks)
{
EntityResolutionIgnoreRules = rules.ToArray();
PluginFolderCreators = pluginFolders.ToArray();
@ -226,7 +226,6 @@ namespace MediaBrowser.Server.Implementations.Library
PrescanTasks = prescanTasks;
PostscanTasks = postscanTasks;
PeoplePrescanTasks = peoplePrescanTasks;
_savers = savers;
}
/// <summary>
@ -1375,9 +1374,9 @@ namespace MediaBrowser.Server.Implementations.Library
{
if (item.LocationType == LocationType.FileSystem)
{
await SaveMetadata(item, updateReason).ConfigureAwait(false);
await _providerManagerFactory().SaveMetadata(item, updateReason).ConfigureAwait(false);
}
item.DateLastSaved = DateTime.UtcNow;
await ItemRepository.SaveItem(item, cancellationToken).ConfigureAwait(false);
@ -1440,49 +1439,6 @@ namespace MediaBrowser.Server.Implementations.Library
return ItemRepository.RetrieveItem(id);
}
private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
/// <summary>
/// Saves the metadata.
/// </summary>
/// <param name="item">The item.</param>
/// <param name="updateType">Type of the update.</param>
/// <returns>Task.</returns>
public async Task SaveMetadata(BaseItem item, ItemUpdateType updateType)
{
var locationType = item.LocationType;
if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
{
throw new ArgumentException("Only file-system based items can save metadata.");
}
foreach (var saver in _savers.Where(i => i.IsEnabledFor(item, updateType)))
{
var path = saver.GetSavePath(item);
var semaphore = _fileLocks.GetOrAdd(path, key => new SemaphoreSlim(1, 1));
var libraryMonitor = _libraryMonitorFactory();
await semaphore.WaitAsync().ConfigureAwait(false);
try
{
libraryMonitor.ReportFileSystemChangeBeginning(path);
saver.Save(item, CancellationToken.None);
}
catch (Exception ex)
{
_logger.ErrorException("Error in metadata saver", ex);
}
finally
{
libraryMonitor.ReportFileSystemChangeComplete(path, false);
semaphore.Release();
}
}
}
/// <summary>
/// Finds the type of the collection.
/// </summary>

@ -282,7 +282,7 @@ namespace MediaBrowser.ServerApplication
UserManager = new UserManager(Logger, ServerConfigurationManager, UserRepository);
RegisterSingleInstance(UserManager);
LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager);
LibraryManager = new LibraryManager(Logger, TaskManager, UserManager, ServerConfigurationManager, UserDataManager, () => LibraryMonitor, FileSystemManager, () => ProviderManager);
RegisterSingleInstance(LibraryManager);
LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager);
@ -499,10 +499,10 @@ namespace MediaBrowser.ServerApplication
GetExports<IBaseItemComparer>(),
GetExports<ILibraryPrescanTask>(),
GetExports<ILibraryPostScanTask>(),
GetExports<IPeoplePrescanTask>(),
GetExports<IMetadataSaver>());
GetExports<IPeoplePrescanTask>());
ProviderManager.AddParts(GetExports<BaseMetadataProvider>(), GetExports<IImageProvider>(), GetExports<IMetadataService>(), GetExports<IMetadataProvider>());
ProviderManager.AddParts(GetExports<BaseMetadataProvider>(), GetExports<IImageProvider>(), GetExports<IMetadataService>(), GetExports<IMetadataProvider>(),
GetExports<IMetadataSaver>());
ImageProcessor.AddParts(GetExports<IImageEnhancer>());

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
<version>3.0.310</version>
<version>3.0.317</version>
<title>MediaBrowser.Common.Internal</title>
<authors>Luke</authors>
<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>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.310" />
<dependency id="MediaBrowser.Common" version="3.0.317" />
<dependency id="NLog" version="2.1.0" />
<dependency id="SimpleInjector" version="2.4.1" />
<dependency id="sharpcompress" version="0.10.2" />

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
<version>3.0.310</version>
<version>3.0.317</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>

@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
<version>3.0.310</version>
<version>3.0.317</version>
<title>Media Browser.Server.Core</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
@ -12,7 +12,7 @@
<description>Contains core components required to build plugins for Media Browser Server.</description>
<copyright>Copyright © Media Browser 2013</copyright>
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.310" />
<dependency id="MediaBrowser.Common" version="3.0.317" />
</dependencies>
</metadata>
<files>

Loading…
Cancel
Save