aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-02-03 00:35:43 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-02-03 00:35:43 -0500
commit30ebfab8e0ae39213a5a550fbcbaa2463d6a74da (patch)
treefe6614f197b623917d0034bfec02c5d500f81ab9
parent6261f157f340e4f544f8f41a81b3cc1f2c69f5b1 (diff)
converted season providers
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs8
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs9
-rw-r--r--MediaBrowser.Controller/Entities/User.cs27
-rw-r--r--MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs2
-rw-r--r--MediaBrowser.Providers/Games/GameSystemXmlProvider.cs2
-rw-r--r--MediaBrowser.Providers/Games/GameXmlProvider.cs2
-rw-r--r--MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs2
-rw-r--r--MediaBrowser.Providers/Manager/MetadataService.cs31
-rw-r--r--MediaBrowser.Providers/MediaBrowser.Providers.csproj13
-rw-r--r--MediaBrowser.Providers/Music/AlbumXmlProvider.cs2
-rw-r--r--MediaBrowser.Providers/Music/ArtistXmlProvider.cs2
-rw-r--r--MediaBrowser.Providers/People/PersonXmlProvider.cs2
-rw-r--r--MediaBrowser.Providers/Savers/AlbumXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/ArtistXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/ChannelXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/FolderXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/GameXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/MovieXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/PersonXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/SeasonXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/Savers/SeriesXmlSaver.cs2
-rw-r--r--MediaBrowser.Providers/TV/FanArtSeasonProvider.cs339
-rw-r--r--MediaBrowser.Providers/TV/FanArtTVProvider.cs23
-rw-r--r--MediaBrowser.Providers/TV/ManualFanartSeasonProvider.cs276
-rw-r--r--MediaBrowser.Providers/TV/SeasonIndexNumberProvider.cs83
-rw-r--r--MediaBrowser.Providers/TV/SeasonMetadataService.cs58
-rw-r--r--MediaBrowser.Providers/TV/SeasonProviderFromXml.cs97
-rw-r--r--MediaBrowser.Providers/TV/SeasonXmlProvider.cs63
-rw-r--r--MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs (renamed from MediaBrowser.Providers/TV/ManualTvdbSeasonImageProvider.cs)47
-rw-r--r--MediaBrowser.Providers/TV/TvdbSeasonProvider.cs211
-rw-r--r--MediaBrowser.Providers/TV/TvdbSeriesProvider.cs20
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec4
-rw-r--r--Nuget/MediaBrowser.Common.nuspec2
-rw-r--r--Nuget/MediaBrowser.Server.Core.nuspec4
37 files changed, 493 insertions, 860 deletions
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index d9579d79f..5a041860b 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -784,11 +784,19 @@ namespace MediaBrowser.Controller.Entities
ResetResolveArgs();
}
+ await BeforeRefreshMetadata(options, cancellationToken).ConfigureAwait(false);
+
await ProviderManager.RefreshMetadata(this, options, cancellationToken).ConfigureAwait(false);
return false;
}
+ private readonly Task _cachedTask = Task.FromResult(true);
+ protected virtual Task BeforeRefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken)
+ {
+ return _cachedTask;
+ }
+
[Obsolete]
public virtual async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
{
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index a4257b2a5..94db04864 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -914,11 +914,14 @@ namespace MediaBrowser.Controller.Entities
return item;
}
- public override async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
+ protected override Task BeforeRefreshMetadata(MetadataRefreshOptions options, CancellationToken cancellationToken)
{
- var changed = await base.RefreshMetadataDirect(cancellationToken, forceSave, forceRefresh).ConfigureAwait(false);
+ if (SupportsShortcutChildren && LocationType == LocationType.FileSystem)
+ {
+ RefreshLinkedChildren();
+ }
- return (SupportsShortcutChildren && LocationType == LocationType.FileSystem && RefreshLinkedChildren()) || changed;
+ return base.BeforeRefreshMetadata(options, cancellationToken);
}
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index c109e1d0c..5feb000af 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -275,33 +275,6 @@ namespace MediaBrowser.Controller.Entities
}
/// <summary>
- /// Refresh metadata on us by execution our provider chain
- /// The item will be persisted if a change is made by a provider, or if it's new or changed.
- /// </summary>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <param name="forceSave">if set to <c>true</c> [is new item].</param>
- /// <param name="forceRefresh">if set to <c>true</c> [force].</param>
- /// <returns>true if a provider reports we changed</returns>
- public override async Task<bool> RefreshMetadataDirect(CancellationToken cancellationToken, bool forceSave = false, bool forceRefresh = false)
- {
- // Reload this
- ResetResolveArgs();
-
- var updateReason = await ProviderManager.ExecuteMetadataProviders(this, cancellationToken, forceRefresh).ConfigureAwait(false);
-
- var changed = updateReason.HasValue;
-
- if (changed || forceSave)
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- await UserManager.UpdateUser(this).ConfigureAwait(false);
- }
-
- return changed;
- }
-
- /// <summary>
/// Updates the configuration.
/// </summary>
/// <param name="config">The config.</param>
diff --git a/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs b/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs
index 391dd456e..64de1c37f 100644
--- a/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs
+++ b/MediaBrowser.Providers/BoxSets/BoxSetXmlProvider.cs
@@ -51,7 +51,7 @@ namespace MediaBrowser.Providers.BoxSets
public string Name
{
- get { return "Media Browser xml"; }
+ get { return "Media Browser Xml"; }
}
protected override FileInfo GetXmlFile(string path)
diff --git a/MediaBrowser.Providers/Games/GameSystemXmlProvider.cs b/MediaBrowser.Providers/Games/GameSystemXmlProvider.cs
index f2001f586..61fb791e6 100644
--- a/MediaBrowser.Providers/Games/GameSystemXmlProvider.cs
+++ b/MediaBrowser.Providers/Games/GameSystemXmlProvider.cs
@@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Games
public string Name
{
- get { return "Media Browser xml"; }
+ get { return "Media Browser Xml"; }
}
protected override FileInfo GetXmlFile(string path)
diff --git a/MediaBrowser.Providers/Games/GameXmlProvider.cs b/MediaBrowser.Providers/Games/GameXmlProvider.cs
index fb64c2a61..e2a67de8d 100644
--- a/MediaBrowser.Providers/Games/GameXmlProvider.cs
+++ b/MediaBrowser.Providers/Games/GameXmlProvider.cs
@@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Games
public string Name
{
- get { return "Media Browser xml"; }
+ get { return "Media Browser Xml"; }
}
protected override FileInfo GetXmlFile(string path)
diff --git a/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs b/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs
index 096e68a8a..701cc9f85 100644
--- a/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs
+++ b/MediaBrowser.Providers/LiveTv/ChannelXmlProvider.cs
@@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.LiveTv
public string Name
{
- get { return "Media Browser xml"; }
+ get { return "Media Browser Xml"; }
}
protected override FileInfo GetXmlFile(string path)
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index f6e27238e..47345126d 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -89,6 +89,8 @@ namespace MediaBrowser.Providers.Manager
// Next run metadata providers
if (refreshOptions.MetadataRefreshMode != MetadataRefreshMode.None)
{
+ updateType = updateType | BeforeMetadataRefresh(itemOfType);
+
var providers = GetProviders(item, lastResult.DateLastMetadataRefresh.HasValue, refreshOptions).ToList();
if (providers.Count > 0)
@@ -100,6 +102,8 @@ namespace MediaBrowser.Providers.Manager
refreshResult.SetDateLastMetadataRefresh(DateTime.UtcNow);
refreshResult.AddImageProvidersRefreshed(result.Providers);
}
+
+ updateType = updateType | AfterMetadataRefresh(itemOfType);
}
// Next run remote image providers, but only if local image providers didn't throw an exception
@@ -116,8 +120,6 @@ namespace MediaBrowser.Providers.Manager
refreshResult.SetDateLastImagesRefresh(DateTime.UtcNow);
refreshResult.AddImageProvidersRefreshed(result.Providers);
}
-
- updateType = updateType | AfterMetadataRefresh(itemOfType);
}
var providersHadChanges = updateType > ItemUpdateType.Unspecified;
@@ -158,6 +160,16 @@ namespace MediaBrowser.Providers.Manager
}
/// <summary>
+ /// Befores the metadata refresh.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <returns>ItemUpdateType.</returns>
+ protected virtual ItemUpdateType BeforeMetadataRefresh(TItemType item)
+ {
+ return ItemUpdateType.Unspecified;
+ }
+
+ /// <summary>
/// Gets the providers.
/// </summary>
/// <param name="item">The item.</param>
@@ -261,12 +273,17 @@ namespace MediaBrowser.Providers.Manager
if (localItem.HasMetadata)
{
- MergeData(localItem.Item, temp, new List<MetadataFields>(), !options.ReplaceAllMetadata, true);
- refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport;
+ if (!string.IsNullOrEmpty(localItem.Item.Name))
+ {
+ MergeData(localItem.Item, temp, new List<MetadataFields>(), !options.ReplaceAllMetadata, true);
+ refreshResult.UpdateType = refreshResult.UpdateType | ItemUpdateType.MetadataImport;
+
+ // Only one local provider allowed per item
+ hasLocalMetadata = true;
+ break;
+ }
- // Only one local provider allowed per item
- hasLocalMetadata = true;
- break;
+ Logger.Error("Invalid local metadata found for: " + item.Path);
}
}
catch (OperationCanceledException)
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 9170e7268..282facfc8 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -65,6 +65,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="All\LocalImageProvider.cs" />
+ <Compile Include="Books\BookMetadataService.cs" />
<Compile Include="BoxSets\BoxSetMetadataService.cs" />
<Compile Include="BoxSets\MovieDbBoxSetImageProvider.cs" />
<Compile Include="BoxSets\MovieDbBoxSetProvider.cs" />
@@ -151,26 +152,24 @@
<Compile Include="TV\EpisodeIndexNumberProvider.cs" />
<Compile Include="TV\EpisodeProviderFromXml.cs" />
<Compile Include="TV\EpisodeXmlParser.cs" />
- <Compile Include="TV\FanArtSeasonProvider.cs" />
<Compile Include="TV\FanArtTVProvider.cs" />
<Compile Include="TV\FanArtTvUpdatesPrescanTask.cs" />
- <Compile Include="TV\ManualFanartSeasonProvider.cs" />
+ <Compile Include="TV\FanartSeasonProvider.cs" />
<Compile Include="TV\ManualFanartSeriesProvider.cs" />
<Compile Include="TV\ManualTvdbEpisodeImageProvider.cs" />
<Compile Include="People\TvdbPersonImageProvider.cs" />
- <Compile Include="TV\ManualTvdbSeasonImageProvider.cs" />
+ <Compile Include="TV\TvdbSeasonImageProvider.cs" />
<Compile Include="TV\ManualTvdbSeriesImageProvider.cs" />
- <Compile Include="TV\SeasonIndexNumberProvider.cs" />
+ <Compile Include="TV\SeasonMetadataService.cs" />
<Compile Include="TV\TvdbEpisodeProvider.cs" />
- <Compile Include="TV\TvdbSeasonProvider.cs" />
+ <Compile Include="TV\TvdbSeriesImageProvider.cs" />
<Compile Include="TV\TvdbSeriesProvider.cs" />
- <Compile Include="TV\SeasonProviderFromXml.cs" />
+ <Compile Include="TV\SeasonXmlProvider.cs" />
<Compile Include="TV\SeriesDynamicInfoProvider.cs" />
<Compile Include="TV\SeriesPostScanTask.cs" />
<Compile Include="TV\SeriesProviderFromXml.cs" />
<Compile Include="TV\SeriesXmlParser.cs" />
<Compile Include="TV\TvdbPrescanTask.cs" />
- <Compile Include="TV\TvdbSeriesImageProvider.cs" />
<Compile Include="UserRootFolderNameProvider.cs" />
<Compile Include="Users\UserMetadataService.cs" />
<Compile Include="VirtualItemImageValidator.cs" />
diff --git a/MediaBrowser.Providers/Music/AlbumXmlProvider.cs b/MediaBrowser.Providers/Music/AlbumXmlProvider.cs
index e0d830369..7c7de6182 100644
--- a/MediaBrowser.Providers/Music/AlbumXmlProvider.cs
+++ b/MediaBrowser.Providers/Music/AlbumXmlProvider.cs
@@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Music
public string Name
{
- get { return "Media Browser xml"; }
+ get { return "Media Browser Xml"; }
}
protected override FileInfo GetXmlFile(string path)
diff --git a/MediaBrowser.Providers/Music/ArtistXmlProvider.cs b/MediaBrowser.Providers/Music/ArtistXmlProvider.cs
index 3f073d512..30c38bdaa 100644
--- a/MediaBrowser.Providers/Music/ArtistXmlProvider.cs
+++ b/MediaBrowser.Providers/Music/ArtistXmlProvider.cs
@@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.Music
public string Name
{
- get { return "Media Browser xml"; }
+ get { return "Media Browser Xml"; }
}
protected override FileInfo GetXmlFile(string path)
diff --git a/MediaBrowser.Providers/People/PersonXmlProvider.cs b/MediaBrowser.Providers/People/PersonXmlProvider.cs
index 72aef7a4c..c23458f68 100644
--- a/MediaBrowser.Providers/People/PersonXmlProvider.cs
+++ b/MediaBrowser.Providers/People/PersonXmlProvider.cs
@@ -48,7 +48,7 @@ namespace MediaBrowser.Providers.People
public string Name
{
- get { return "Media Browser xml"; }
+ get { return "Media Browser Xml"; }
}
protected override FileInfo GetXmlFile(string path)
diff --git a/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs b/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs
index 34f91ba28..bc51a5286 100644
--- a/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/AlbumXmlSaver.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs b/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs
index 5c40f3b38..1ae1eaa64 100644
--- a/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/ArtistXmlSaver.cs
@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs
index 35c53115d..06a17528b 100644
--- a/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/BoxSetXmlSaver.cs
@@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs b/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs
index 3d8cbb415..0c857c5ec 100644
--- a/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/ChannelXmlSaver.cs
@@ -37,7 +37,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
index c1f6bb7de..e60acaa38 100644
--- a/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/EpisodeXmlSaver.cs
@@ -41,7 +41,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs
index fe8eec3a5..e0ae638e9 100644
--- a/MediaBrowser.Providers/Savers/FolderXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/FolderXmlSaver.cs
@@ -25,7 +25,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs b/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs
index 38af31923..017f17f8d 100644
--- a/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/GameSystemXmlSaver.cs
@@ -23,7 +23,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/GameXmlSaver.cs b/MediaBrowser.Providers/Savers/GameXmlSaver.cs
index b9abb3773..a6225b58c 100644
--- a/MediaBrowser.Providers/Savers/GameXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/GameXmlSaver.cs
@@ -28,7 +28,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
index 2c19cb628..e5ba1aefd 100644
--- a/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/MovieXmlSaver.cs
@@ -32,7 +32,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/PersonXmlSaver.cs b/MediaBrowser.Providers/Savers/PersonXmlSaver.cs
index 12703aa3c..167e514a8 100644
--- a/MediaBrowser.Providers/Savers/PersonXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/PersonXmlSaver.cs
@@ -18,7 +18,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs
index 6c4d3fb19..5773fc1de 100644
--- a/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/SeasonXmlSaver.cs
@@ -22,7 +22,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
index 21019fa0e..b76167868 100644
--- a/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
+++ b/MediaBrowser.Providers/Savers/SeriesXmlSaver.cs
@@ -24,7 +24,7 @@ namespace MediaBrowser.Providers.Savers
{
get
{
- return "Media Browser xml";
+ return "Media Browser Xml";
}
}
diff --git a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
index 50db33b3d..60643252b 100644
--- a/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtSeasonProvider.cs
@@ -1,190 +1,303 @@
using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Configuration;
+using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
+using MediaBrowser.Providers.Music;
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.IO;
using System.Linq;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Model.Net;
-using System.Net;
-using MediaBrowser.Providers.Music;
+using System.Xml;
namespace MediaBrowser.Providers.TV
{
- /// <summary>
- /// Class FanArtSeasonProvider
- /// </summary>
- class FanArtSeasonProvider : BaseMetadataProvider
+ public class FanartSeasonImageProvider : IRemoteImageProvider, IHasOrder, IHasChangeMonitor
{
- /// <summary>
- /// The _provider manager
- /// </summary>
- private readonly IProviderManager _providerManager;
+ private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+ private readonly IServerConfigurationManager _config;
+ private readonly IHttpClient _httpClient;
private readonly IFileSystem _fileSystem;
- /// <summary>
- /// Initializes a new instance of the <see cref="FanArtSeasonProvider"/> class.
- /// </summary>
- /// <param name="logManager">The log manager.</param>
- /// <param name="configurationManager">The configuration manager.</param>
- /// <param name="providerManager">The provider manager.</param>
- public FanArtSeasonProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
- : base(logManager, configurationManager)
+ public FanartSeasonImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
{
- _providerManager = providerManager;
+ _config = config;
+ _httpClient = httpClient;
_fileSystem = fileSystem;
}
- public override ItemUpdateType ItemUpdateType
+ public string Name
{
- get
- {
- return ItemUpdateType.ImageUpdate;
- }
+ get { return ProviderName; }
}
-
- /// <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)
+
+ public static string ProviderName
+ {
+ get { return "FanArt"; }
+ }
+
+ public bool Supports(IHasImages item)
{
return item is Season;
}
- /// <summary>
- /// Gets the priority.
- /// </summary>
- /// <value>The priority.</value>
- public override MetadataProviderPriority Priority
+ public IEnumerable<ImageType> GetSupportedImages(IHasImages item)
{
- get { return MetadataProviderPriority.Third; }
+ return new List<ImageType>
+ {
+ ImageType.Backdrop,
+ ImageType.Thumb
+ };
}
- protected override DateTime CompareDate(BaseItem item)
+ public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
{
+ var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
+
+ return images.Where(i => i.Type == imageType);
+ }
+
+ public async Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
+ {
+ var list = new List<RemoteImageInfo>();
+
var season = (Season)item;
- var seriesId = season.Series != null ? season.Series.GetProviderId(MetadataProviders.Tvdb) : null;
+ var series = season.Series;
- if (!string.IsNullOrEmpty(seriesId))
+ if (series != null)
{
- // Process images
- var imagesXmlPath = FanArtTvProvider.Current.GetFanartXmlPath(seriesId);
+ var id = series.GetProviderId(MetadataProviders.Tvdb);
- var imagesFileInfo = new FileInfo(imagesXmlPath);
-
- if (imagesFileInfo.Exists)
+ if (!string.IsNullOrEmpty(id) && season.IndexNumber.HasValue)
{
- return _fileSystem.GetLastWriteTimeUtc(imagesFileInfo);
+ await FanArtTvProvider.Current.EnsureSeriesXml(id, cancellationToken).ConfigureAwait(false);
+
+ var xmlPath = FanArtTvProvider.Current.GetFanartXmlPath(id);
+
+ try
+ {
+ AddImages(list, season.IndexNumber.Value, xmlPath, cancellationToken);
+ }
+ catch (FileNotFoundException)
+ {
+ // No biggie. Don't blow up
+ }
}
}
- return base.CompareDate(item);
+ var language = item.GetPreferredMetadataLanguage();
+
+ var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase);
+
+ // Sort first by width to prioritize HD versions
+ return list.OrderByDescending(i => i.Width ?? 0)
+ .ThenByDescending(i =>
+ {
+ if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase))
+ {
+ return 3;
+ }
+ if (!isLanguageEn)
+ {
+ if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
+ {
+ return 2;
+ }
+ }
+ if (string.IsNullOrEmpty(i.Language))
+ {
+ return isLanguageEn ? 3 : 2;
+ }
+ return 0;
+ })
+ .ThenByDescending(i => i.CommunityRating ?? 0)
+ .ThenByDescending(i => i.VoteCount ?? 0);
}
- /// <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)
+ private void AddImages(List<RemoteImageInfo> list, int seasonNumber, string xmlPath, CancellationToken cancellationToken)
{
- cancellationToken.ThrowIfCancellationRequested();
+ using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
+ {
+ // Use XmlReader for best performance
+ using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
+ {
+ CheckCharacters = false,
+ IgnoreProcessingInstructions = true,
+ IgnoreComments = true,
+ ValidationType = ValidationType.None
+ }))
+ {
+ reader.MoveToContent();
- var season = (Season) item;
+ // Loop through each element
+ while (reader.Read())
+ {
+ cancellationToken.ThrowIfCancellationRequested();
- // Process images
- var images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualFanartSeasonImageProvider.ProviderName).ConfigureAwait(false);
- await FetchImages(season, images.ToList(), cancellationToken).ConfigureAwait(false);
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "series":
+ {
+ using (var subReader = reader.ReadSubtree())
+ {
+ AddImages(list, subReader, seasonNumber, cancellationToken);
+ }
+ break;
+ }
- SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
- return true;
+ default:
+ reader.Skip();
+ break;
+ }
+ }
+ }
+ }
+ }
}
- /// <summary>
- /// Fetches the images.
- /// </summary>
- /// <param name="season">The season.</param>
- /// <param name="images">The images.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- private async Task FetchImages(Season season, List<RemoteImageInfo> images, CancellationToken cancellationToken)
+ private void AddImages(List<RemoteImageInfo> list, XmlReader reader, int seasonNumber, CancellationToken cancellationToken)
{
- var options = ConfigurationManager.Configuration.GetMetadataOptions("Season") ?? new MetadataOptions();
+ reader.MoveToContent();
- if (options.IsEnabled(ImageType.Thumb) && !season.HasImage(ImageType.Thumb) && !season.LockedFields.Contains(MetadataFields.Images))
+ while (reader.Read())
{
- await SaveImage(season, images, ImageType.Thumb, cancellationToken).ConfigureAwait(false);
+ if (reader.NodeType == XmlNodeType.Element)
+ {
+ switch (reader.Name)
+ {
+ case "seasonthumbs":
+ {
+ using (var subReader = reader.ReadSubtree())
+ {
+ PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 500, 281, seasonNumber);
+ }
+ break;
+ }
+ case "showbackgrounds":
+ {
+ using (var subReader = reader.ReadSubtree())
+ {
+ PopulateImageCategory(list, subReader, cancellationToken, ImageType.Backdrop, 1920, 1080, seasonNumber);
+ }
+ break;
+ }
+ default:
+ {
+ using (reader.ReadSubtree())
+ {
+ }
+ break;
+ }
+ }
+ }
}
}
- private async Task SaveImage(BaseItem item, List<RemoteImageInfo> images, ImageType type, CancellationToken cancellationToken)
+ private void PopulateImageCategory(List<RemoteImageInfo> list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height, int seasonNumber)
{
- foreach (var image in images.Where(i => i.Type == type))
+ reader.MoveToContent();
+
+ while (reader.Read())
{
- try
- {
- await _providerManager.SaveImage(item, image.Url, FanartArtistProvider.FanArtResourcePool, type, null, cancellationToken).ConfigureAwait(false);
- break;
- }
- catch (HttpException ex)
+ cancellationToken.ThrowIfCancellationRequested();
+
+ if (reader.NodeType == XmlNodeType.Element)
{
- // Sometimes fanart has bad url's in their xml
- if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
+ switch (reader.Name)
{
- continue;
+ case "seasonthumb":
+ case "showbackground":
+ {
+ var url = reader.GetAttribute("url");
+ var season = reader.GetAttribute("season");
+
+ int imageSeasonNumber;
+
+ if (!string.IsNullOrEmpty(url) &&
+ !string.IsNullOrEmpty(season) &&
+ int.TryParse(season, NumberStyles.Any, _usCulture, out imageSeasonNumber) &&
+ seasonNumber == imageSeasonNumber)
+ {
+ var likesString = reader.GetAttribute("likes");
+ int likes;
+
+ var info = new RemoteImageInfo
+ {
+ RatingType = RatingType.Likes,
+ Type = type,
+ Width = width,
+ Height = height,
+ ProviderName = Name,
+ Url = url,
+ Language = reader.GetAttribute("lang")
+ };
+
+ if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
+ {
+ info.CommunityRating = likes;
+ }
+
+ list.Add(info);
+ }
+
+ break;
+ }
+ default:
+ reader.Skip();
+ break;
}
- break;
}
}
}
- /// <summary>
- /// Gets a value indicating whether [requires internet].
- /// </summary>
- /// <value><c>true</c> if [requires internet]; otherwise, <c>false</c>.</value>
- public override bool RequiresInternet
+ public int Order
{
- get
- {
- return true;
- }
+ get { return 1; }
}
- /// <summary>
- /// Gets a value indicating whether [refresh on version change].
- /// </summary>
- /// <value><c>true</c> if [refresh on version change]; otherwise, <c>false</c>.</value>
- protected override bool RefreshOnVersionChange
+ public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
{
- get
+ return _httpClient.GetResponse(new HttpRequestOptions
{
- return true;
- }
+ CancellationToken = cancellationToken,
+ Url = url,
+ ResourcePool = FanartArtistProvider.FanArtResourcePool
+ });
}
- /// <summary>
- /// Gets the provider version.
- /// </summary>
- /// <value>The provider version.</value>
- protected override string ProviderVersion
+ public bool HasChanged(IHasMetadata item, DateTime date)
{
- get
+ var season = (Season)item;
+ var series = season.Series;
+
+ if (series == null)
{
- return "3";
+ return false;
}
+
+ var tvdbId = series.GetProviderId(MetadataProviders.Tvdb);
+
+ if (!String.IsNullOrEmpty(tvdbId))
+ {
+ // Process images
+ var imagesXmlPath = FanArtTvProvider.Current.GetFanartXmlPath(tvdbId);
+
+ var fileInfo = new FileInfo(imagesXmlPath);
+
+ return fileInfo.Exists && _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
+ }
+
+ return false;
}
}
}
diff --git a/MediaBrowser.Providers/TV/FanArtTVProvider.cs b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
index 3f2199fc4..baadf350f 100644
--- a/MediaBrowser.Providers/TV/FanArtTVProvider.cs
+++ b/MediaBrowser.Providers/TV/FanArtTVProvider.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.Providers.TV
return ItemUpdateType.ImageUpdate;
}
}
-
+
/// <summary>
/// Needses the refresh internal.
/// </summary>
@@ -160,7 +160,7 @@ namespace MediaBrowser.Providers.TV
var dataPath = GetSeriesDataPath(ConfigurationManager.ApplicationPaths, tvdbId);
return Path.Combine(dataPath, "fanart.xml");
}
-
+
protected readonly CultureInfo UsCulture = new CultureInfo("en-US");
public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
@@ -199,7 +199,7 @@ namespace MediaBrowser.Providers.TV
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();
@@ -278,6 +278,23 @@ namespace MediaBrowser.Providers.TV
}
}
+ internal Task EnsureSeriesXml(string tvdbId, CancellationToken cancellationToken)
+ {
+ var xmlPath = GetSeriesDataPath(ConfigurationManager.ApplicationPaths, tvdbId);
+
+ var fileInfo = _fileSystem.GetFileSystemInfo(xmlPath);
+
+ if (fileInfo.Exists)
+ {
+ if (ConfigurationManager.Configuration.EnableFanArtUpdates || (DateTime.UtcNow - _fileSystem.GetLastWriteTimeUtc(fileInfo)).TotalDays <= 7)
+ {
+ return Task.FromResult(true);
+ }
+ }
+
+ return DownloadSeriesXml(tvdbId, cancellationToken);
+ }
+
/// <summary>
/// Downloads the series XML.
/// </summary>
diff --git a/MediaBrowser.Providers/TV/ManualFanartSeasonProvider.cs b/MediaBrowser.Providers/TV/ManualFanartSeasonProvider.cs
deleted file mode 100644
index c7b2f595b..000000000
--- a/MediaBrowser.Providers/TV/ManualFanartSeasonProvider.cs
+++ /dev/null
@@ -1,276 +0,0 @@
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Providers;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Xml;
-using MediaBrowser.Providers.Music;
-
-namespace MediaBrowser.Providers.TV
-{
- public class ManualFanartSeasonImageProvider : IRemoteImageProvider, IHasOrder
- {
- private readonly CultureInfo _usCulture = new CultureInfo("en-US");
- private readonly IServerConfigurationManager _config;
- private readonly IHttpClient _httpClient;
-
- public ManualFanartSeasonImageProvider(IServerConfigurationManager config, IHttpClient httpClient)
- {
- _config = config;
- _httpClient = httpClient;
- }
-
- public string Name
- {
- get { return ProviderName; }
- }
-
- public static string ProviderName
- {
- get { return "FanArt"; }
- }
-
- public bool Supports(IHasImages item)
- {
- return item is Season;
- }
-
- public IEnumerable<ImageType> GetSupportedImages(IHasImages item)
- {
- return new List<ImageType>
- {
- ImageType.Backdrop,
- ImageType.Thumb
- };
- }
-
- public async Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, ImageType imageType, CancellationToken cancellationToken)
- {
- var images = await GetAllImages(item, cancellationToken).ConfigureAwait(false);
-
- return images.Where(i => i.Type == imageType);
- }
-
- public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
- {
- var list = new List<RemoteImageInfo>();
-
- var season = (Season)item;
- var series = season.Series;
-
- if (series != null)
- {
- var id = series.GetProviderId(MetadataProviders.Tvdb);
-
- if (!string.IsNullOrEmpty(id) && season.IndexNumber.HasValue)
- {
- var xmlPath = FanArtTvProvider.Current.GetFanartXmlPath(id);
-
- try
- {
- AddImages(list, season.IndexNumber.Value, xmlPath, cancellationToken);
- }
- catch (FileNotFoundException)
- {
- // No biggie. Don't blow up
- }
- }
- }
-
- var language = item.GetPreferredMetadataLanguage();
-
- var isLanguageEn = string.Equals(language, "en", StringComparison.OrdinalIgnoreCase);
-
- // Sort first by width to prioritize HD versions
- list = list.OrderByDescending(i => i.Width ?? 0)
- .ThenByDescending(i =>
- {
- if (string.Equals(language, i.Language, StringComparison.OrdinalIgnoreCase))
- {
- return 3;
- }
- if (!isLanguageEn)
- {
- if (string.Equals("en", i.Language, StringComparison.OrdinalIgnoreCase))
- {
- return 2;
- }
- }
- if (string.IsNullOrEmpty(i.Language))
- {
- return isLanguageEn ? 3 : 2;
- }
- return 0;
- })
- .ThenByDescending(i => i.CommunityRating ?? 0)
- .ThenByDescending(i => i.VoteCount ?? 0)
- .ToList();
-
- return Task.FromResult<IEnumerable<RemoteImageInfo>>(list);
- }
-
- private void AddImages(List<RemoteImageInfo> list, int seasonNumber, string xmlPath, CancellationToken cancellationToken)
- {
- using (var streamReader = new StreamReader(xmlPath, Encoding.UTF8))
- {
- // Use XmlReader for best performance
- using (var reader = XmlReader.Create(streamReader, new XmlReaderSettings
- {
- CheckCharacters = false,
- IgnoreProcessingInstructions = true,
- IgnoreComments = true,
- ValidationType = ValidationType.None
- }))
- {
- reader.MoveToContent();
-
- // Loop through each element
- while (reader.Read())
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "series":
- {
- using (var subReader = reader.ReadSubtree())
- {
- AddImages(list, subReader, seasonNumber, cancellationToken);
- }
- break;
- }
-
- default:
- reader.Skip();
- break;
- }
- }
- }
- }
- }
- }
-
- private void AddImages(List<RemoteImageInfo> list, XmlReader reader, int seasonNumber, CancellationToken cancellationToken)
- {
- reader.MoveToContent();
-
- while (reader.Read())
- {
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "seasonthumbs":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Thumb, 500, 281, seasonNumber);
- }
- break;
- }
- case "showbackgrounds":
- {
- using (var subReader = reader.ReadSubtree())
- {
- PopulateImageCategory(list, subReader, cancellationToken, ImageType.Backdrop, 1920, 1080, seasonNumber);
- }
- break;
- }
- default:
- {
- using (reader.ReadSubtree())
- {
- }
- break;
- }
- }
- }
- }
- }
-
- private void PopulateImageCategory(List<RemoteImageInfo> list, XmlReader reader, CancellationToken cancellationToken, ImageType type, int width, int height, int seasonNumber)
- {
- reader.MoveToContent();
-
- while (reader.Read())
- {
- cancellationToken.ThrowIfCancellationRequested();
-
- if (reader.NodeType == XmlNodeType.Element)
- {
- switch (reader.Name)
- {
- case "seasonthumb":
- case "showbackground":
- {
- var url = reader.GetAttribute("url");
- var season = reader.GetAttribute("season");
-
- int imageSeasonNumber;
-
- if (!string.IsNullOrEmpty(url) &&
- !string.IsNullOrEmpty(season) &&
- int.TryParse(season, NumberStyles.Any, _usCulture, out imageSeasonNumber) &&
- seasonNumber == imageSeasonNumber)
- {
- var likesString = reader.GetAttribute("likes");
- int likes;
-
- var info = new RemoteImageInfo
- {
- RatingType = RatingType.Likes,
- Type = type,
- Width = width,
- Height = height,
- ProviderName = Name,
- Url = url,
- Language = reader.GetAttribute("lang")
- };
-
- if (!string.IsNullOrEmpty(likesString) && int.TryParse(likesString, NumberStyles.Any, _usCulture, out likes))
- {
- info.CommunityRating = likes;
- }
-
- list.Add(info);
- }
-
- break;
- }
- default:
- reader.Skip();
- break;
- }
- }
- }
- }
-
- public int Order
- {
- get { return 1; }
- }
-
- public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)
- {
- return _httpClient.GetResponse(new HttpRequestOptions
- {
- CancellationToken = cancellationToken,
- Url = url,
- ResourcePool = FanartArtistProvider.FanArtResourcePool
- });
- }
- }
-}
diff --git a/MediaBrowser.Providers/TV/SeasonIndexNumberProvider.cs b/MediaBrowser.Providers/TV/SeasonIndexNumberProvider.cs
deleted file mode 100644
index 593784201..000000000
--- a/MediaBrowser.Providers/TV/SeasonIndexNumberProvider.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Providers;
-using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Logging;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Providers.TV
-{
- class SeasonIndexNumberProvider : BaseMetadataProvider
- {
- /// <summary>
- /// Initializes a new instance of the <see cref="BaseMetadataProvider" /> class.
- /// </summary>
- /// <param name="logManager">The log manager.</param>
- /// <param name="configurationManager">The configuration manager.</param>
- public SeasonIndexNumberProvider(ILogManager logManager, IServerConfigurationManager configurationManager)
- : base(logManager, configurationManager)
- {
- }
-
- protected override bool RefreshOnVersionChange
- {
- get
- {
- return true;
- }
- }
-
- protected override string ProviderVersion
- {
- get
- {
- return "2";
- }
- }
-
- /// <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)
- {
- if (item is Season)
- {
- var locationType = item.LocationType;
- return locationType != LocationType.Virtual && locationType != LocationType.Remote;
- }
- return false;
- }
-
- /// <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="providerInfo">The provider information.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task{System.Boolean}.</returns>
- public override Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken)
- {
- item.IndexNumber = TVUtils.GetSeasonNumberFromPath(item.Path);
-
- SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
-
- return TrueTaskResult;
- }
-
- /// <summary>
- /// Gets the priority.
- /// </summary>
- /// <value>The priority.</value>
- public override MetadataProviderPriority Priority
- {
- get { return MetadataProviderPriority.First; }
- }
- }
-}
diff --git a/MediaBrowser.Providers/TV/SeasonMetadataService.cs b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
new file mode 100644
index 000000000..da276221b
--- /dev/null
+++ b/MediaBrowser.Providers/TV/SeasonMetadataService.cs
@@ -0,0 +1,58 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
+using MediaBrowser.Providers.Manager;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.TV
+{
+ public class SeasonMetadataService : MetadataService<Season, ItemId>
+ {
+ private readonly ILibraryManager _libraryManager;
+
+ public SeasonMetadataService(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(Season source, Season target, List<MetadataFields> lockedFields, bool replaceData, bool mergeMetadataSettings)
+ {
+ ProviderUtils.MergeBaseItemData(source, target, lockedFields, replaceData, mergeMetadataSettings);
+ }
+
+ protected override Task SaveItem(Season item, ItemUpdateType reason, CancellationToken cancellationToken)
+ {
+ return _libraryManager.UpdateItem(item, reason, cancellationToken);
+ }
+
+ protected override ItemUpdateType BeforeMetadataRefresh(Season item)
+ {
+ var updateType = base.BeforeMetadataRefresh(item);
+
+ var currentIndexNumber = item.IndexNumber;
+
+ item.IndexNumber = item.IndexNumber ?? TVUtils.GetSeasonNumberFromPath(item.Path);
+
+ if ((currentIndexNumber ?? -1) != (item.IndexNumber ?? -1))
+ {
+ updateType = updateType | ItemUpdateType.MetadataImport;
+ }
+ return updateType;
+ }
+ }
+}
diff --git a/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs b/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs
deleted file mode 100644
index 9fbcad7c0..000000000
--- a/MediaBrowser.Providers/TV/SeasonProviderFromXml.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Entities.TV;
-using MediaBrowser.Controller.IO;
-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.TV
-{
- /// <summary>
- /// Class SeriesProviderFromXml
- /// </summary>
- public class SeasonProviderFromXml : BaseMetadataProvider
- {
- private readonly IFileSystem _fileSystem;
-
- public SeasonProviderFromXml(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 Season && 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 = "season.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<Season>(Logger).Fetch((Season)item, path, cancellationToken);
- }
- finally
- {
- XmlParsingResourcePool.Release();
- }
-
- SetLastRefreshed(item, DateTime.UtcNow, providerInfo);
-
- return true;
- }
-
- return false;
- }
- }
-}
diff --git a/MediaBrowser.Providers/TV/SeasonXmlProvider.cs b/MediaBrowser.Providers/TV/SeasonXmlProvider.cs
new file mode 100644
index 000000000..9dcc9fe4f
--- /dev/null
+++ b/MediaBrowser.Providers/TV/SeasonXmlProvider.cs
@@ -0,0 +1,63 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Logging;
+using System.IO;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Providers.TV
+{
+ /// <summary>
+ /// Class SeriesProviderFromXml
+ /// </summary>
+ public class SeasonXmlProvider : BaseXmlProvider, ILocalMetadataProvider<Season>
+ {
+ private readonly ILogger _logger;
+
+ public SeasonXmlProvider(IFileSystem fileSystem, ILogger logger)
+ : base(fileSystem)
+ {
+ _logger = logger;
+ }
+
+ public async Task<MetadataResult<Season>> GetMetadata(string path, CancellationToken cancellationToken)
+ {
+ path = GetXmlFile(path).FullName;
+
+ var result = new MetadataResult<Season>();
+
+ await XmlParsingResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ var person = new Season();
+
+ new BaseItemXmlParser<Season>(_logger).Fetch(person, path, cancellationToken);
+ result.HasMetadata = true;
+ result.Item = person;
+ }
+ 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, "season.xml"));
+ }
+ }
+}
+
diff --git a/MediaBrowser.Providers/TV/ManualTvdbSeasonImageProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs
index 458482bf6..a63f3ee24 100644
--- a/MediaBrowser.Providers/TV/ManualTvdbSeasonImageProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbSeasonImageProvider.cs
@@ -1,4 +1,5 @@
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
@@ -19,16 +20,18 @@ using System.Xml;
namespace MediaBrowser.Providers.TV
{
- public class ManualTvdbSeasonImageProvider : IRemoteImageProvider, IHasOrder
+ public class TvdbSeasonImageProvider : IRemoteImageProvider, IHasOrder, IHasChangeMonitor
{
private readonly IServerConfigurationManager _config;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private readonly IHttpClient _httpClient;
+ private readonly IFileSystem _fileSystem;
- public ManualTvdbSeasonImageProvider(IServerConfigurationManager config, IHttpClient httpClient)
+ public TvdbSeasonImageProvider(IServerConfigurationManager config, IHttpClient httpClient, IFileSystem fileSystem)
{
_config = config;
_httpClient = httpClient;
+ _fileSystem = fileSystem;
}
public string Name
@@ -63,14 +66,17 @@ namespace MediaBrowser.Providers.TV
return images.Where(i => i.Type == imageType);
}
- public Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
+ public async Task<IEnumerable<RemoteImageInfo>> GetAllImages(IHasImages item, CancellationToken cancellationToken)
{
var season = (Season)item;
+ var series = season.Series;
- var seriesId = season.Series != null ? season.Series.GetProviderId(MetadataProviders.Tvdb) : null;
+ var seriesId = series != null ? series.GetProviderId(MetadataProviders.Tvdb) : null;
if (!string.IsNullOrEmpty(seriesId) && season.IndexNumber.HasValue)
{
+ await TvdbSeriesProvider.Current.EnsureSeriesInfo(seriesId, series.GetPreferredMetadataLanguage(), cancellationToken).ConfigureAwait(false);
+
// Process images
var seriesDataPath = TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, seriesId);
@@ -78,9 +84,7 @@ namespace MediaBrowser.Providers.TV
try
{
- var result = GetImages(path, item.GetPreferredMetadataLanguage(), season.IndexNumber.Value, cancellationToken);
-
- return Task.FromResult(result);
+ return GetImages(path, item.GetPreferredMetadataLanguage(), season.IndexNumber.Value, cancellationToken);
}
catch (FileNotFoundException)
{
@@ -88,7 +92,7 @@ namespace MediaBrowser.Providers.TV
}
}
- return Task.FromResult<IEnumerable<RemoteImageInfo>>(new RemoteImageInfo[] { });
+ return new RemoteImageInfo[] { };
}
private IEnumerable<RemoteImageInfo> GetImages(string xmlPath, string preferredLanguage, int seasonNumber, CancellationToken cancellationToken)
@@ -335,5 +339,30 @@ namespace MediaBrowser.Providers.TV
ResourcePool = TvdbSeriesProvider.Current.TvDbResourcePool
});
}
+
+ public bool HasChanged(IHasMetadata item, DateTime date)
+ {
+ var season = (Season)item;
+ var series = season.Series;
+
+ if (series == null)
+ {
+ return false;
+ }
+
+ var tvdbId = series.GetProviderId(MetadataProviders.Tvdb);
+
+ if (!String.IsNullOrEmpty(tvdbId))
+ {
+ // Process images
+ var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(_config.ApplicationPaths, tvdbId), "banners.xml");
+
+ var fileInfo = new FileInfo(imagesXmlPath);
+
+ return fileInfo.Exists && _fileSystem.GetLastWriteTimeUtc(fileInfo) > date;
+ }
+
+ return false;
+ }
}
}
diff --git a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs b/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs
deleted file mode 100644
index d7281ac21..000000000
--- a/MediaBrowser.Providers/TV/TvdbSeasonProvider.cs
+++ /dev/null
@@ -1,211 +0,0 @@
-using System.Net;
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Configuration;
-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;
-using MediaBrowser.Model.Providers;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Providers.TV
-{
- /// <summary>
- /// Class RemoteSeasonProvider
- /// </summary>
- class TvdbSeasonProvider : BaseMetadataProvider
- {
- /// <summary>
- /// The _provider manager
- /// </summary>
- private readonly IProviderManager _providerManager;
- private readonly IFileSystem _fileSystem;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="TvdbSeasonProvider"/> class.
- /// </summary>
- /// <param name="logManager">The log manager.</param>
- /// <param name="configurationManager">The configuration manager.</param>
- /// <param name="providerManager">The provider manager.</param>
- /// <exception cref="System.ArgumentNullException">httpClient</exception>
- public TvdbSeasonProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IProviderManager providerManager, IFileSystem fileSystem)
- : base(logManager, configurationManager)
- {
- _providerManager = providerManager;
- _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 Season;
- }
-
- /// <summary>
- /// Gets the priority.
- /// </summary>
- /// <value>The priority.</value>
- public override MetadataProviderPriority Priority
- {
- // Run after fanart
- get { return MetadataProviderPriority.Fourth; }
- }
-
- /// <summary>
- /// Gets a value indicating whether [requires internet].
- /// </summary>
- /// <value><c>true</c> if [requires internet]; otherwise, <c>false</c>.</value>
- public override bool RequiresInternet
- {
- get
- {
- return true;
- }
- }
-
- public override ItemUpdateType ItemUpdateType
- {
- get
- {
- return ItemUpdateType.ImageUpdate;
- }
- }
-
- /// <summary>
- /// Gets a value indicating whether [refresh on version change].
- /// </summary>
- /// <value><c>true</c> if [refresh on version change]; otherwise, <c>false</c>.</value>
- protected override bool RefreshOnVersionChange
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Gets the provider version.
- /// </summary>
- /// <value>The provider version.</value>
- protected override string ProviderVersion
- {
- get
- {
- return "2";
- }
- }
-
- protected override bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
- {
- var season = (Season)item;
- var seriesId = season.Series != null ? season.Series.GetProviderId(MetadataProviders.Tvdb) : null;
-
- if (!string.IsNullOrEmpty(seriesId))
- {
- // Process images
- var imagesXmlPath = Path.Combine(TvdbSeriesProvider.GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId), "banners.xml");
-
- var imagesFileInfo = new FileInfo(imagesXmlPath);
-
- if (imagesFileInfo.Exists)
- {
- return _fileSystem.GetLastWriteTimeUtc(imagesFileInfo) > providerInfo.LastRefreshed;
- }
- }
- return false;
- }
-
- protected override bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
- {
- if (item.HasImage(ImageType.Primary) && item.HasImage(ImageType.Banner) && item.BackdropImagePaths.Count > 0)
- {
- return false;
- }
- return base.NeedsRefreshInternal(item, providerInfo);
- }
-
- /// <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 images = await _providerManager.GetAvailableRemoteImages(item, cancellationToken, ManualTvdbSeasonImageProvider.ProviderName).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, 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))
- {
- await SaveImage(item, images, ImageType.Primary, cancellationToken).ConfigureAwait(false);
- }
-
- if (options.IsEnabled(ImageType.Banner) && !item.HasImage(ImageType.Banner))
- {
- await SaveImage(item, images, ImageType.Banner, cancellationToken).ConfigureAwait(false);
- }
- }
-
- 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;
-
- await _providerManager.SaveImage(item, url, TvdbSeriesProvider.Current.TvDbResourcePool, ImageType.Backdrop, null, cancellationToken).ConfigureAwait(false);
-
- if (item.BackdropImagePaths.Count >= backdropLimit) break;
- }
- }
- }
-
- private async Task SaveImage(BaseItem item, List<RemoteImageInfo> images, ImageType type, CancellationToken cancellationToken)
- {
- foreach (var image in images.Where(i => i.Type == type))
- {
- try
- {
- await _providerManager.SaveImage(item, image.Url, TvdbSeriesProvider.Current.TvDbResourcePool, type, null, cancellationToken).ConfigureAwait(false);
- break;
- }
- catch (HttpException ex)
- {
- // Sometimes fanart has bad url's in their xml
- if (ex.StatusCode.HasValue && ex.StatusCode.Value == HttpStatusCode.NotFound)
- {
- continue;
- }
- break;
- }
- }
- }
- }
-}
diff --git a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
index 4df391e2a..8d7ef5af9 100644
--- a/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbSeriesProvider.cs
@@ -324,6 +324,26 @@ namespace MediaBrowser.Providers.TV
await ExtractEpisodes(seriesDataPath, Path.Combine(seriesDataPath, preferredMetadataLanguage + ".xml"), lastTvDbUpdateTime).ConfigureAwait(false);
}
+ internal async Task EnsureSeriesInfo(string seriesId, string preferredMetadataLanguage, CancellationToken cancellationToken)
+ {
+ var seriesDataPath = GetSeriesDataPath(ConfigurationManager.ApplicationPaths, seriesId);
+
+ Directory.CreateDirectory(seriesDataPath);
+
+ var files = Directory.EnumerateFiles(seriesDataPath, "*.xml", SearchOption.TopDirectoryOnly)
+ .Select(Path.GetFileName)
+ .ToList();
+
+ var seriesXmlFilename = preferredMetadataLanguage + ".xml";
+
+ // Only download if not already there
+ // The prescan task will take care of updates so we don't need to re-download here
+ if (!files.Contains("banners.xml", StringComparer.OrdinalIgnoreCase) || !files.Contains("actors.xml", StringComparer.OrdinalIgnoreCase) || !files.Contains(seriesXmlFilename, StringComparer.OrdinalIgnoreCase))
+ {
+ await DownloadSeriesZip(seriesId, seriesDataPath, null, preferredMetadataLanguage, cancellationToken).ConfigureAwait(false);
+ }
+ }
+
private void DeleteXmlFiles(string path)
{
try
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index daf905a8a..d38e020fa 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common.Internal</id>
- <version>3.0.317</version>
+ <version>3.0.318</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.317" />
+ <dependency id="MediaBrowser.Common" version="3.0.318" />
<dependency id="NLog" version="2.1.0" />
<dependency id="SimpleInjector" version="2.4.1" />
<dependency id="sharpcompress" version="0.10.2" />
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 4a3c25880..5ad30a09f 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MediaBrowser.Common</id>
- <version>3.0.317</version>
+ <version>3.0.318</version>
<title>MediaBrowser.Common</title>
<authors>Media Browser Team</authors>
<owners>ebr,Luke,scottisafool</owners>
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 08f0a1188..a24d6c3ac 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>MediaBrowser.Server.Core</id>
- <version>3.0.317</version>
+ <version>3.0.318</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.317" />
+ <dependency id="MediaBrowser.Common" version="3.0.318" />
</dependencies>
</metadata>
<files>