aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-02-19 00:21:03 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-02-19 00:21:03 -0500
commit4e38c3537398b01776f6e1c5e1c08bce73eec82e (patch)
tree3fc399f51419d6aae3ae8d96769995cc28191d1f
parentcf4ae16f18376c38fed7a8fcaefdc883893473a2 (diff)
fixed remote control flyout
-rw-r--r--MediaBrowser.Api/ItemUpdateService.cs18
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs12
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicArtist.cs2
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs10
-rw-r--r--MediaBrowser.Controller/Entities/Folder.cs2
-rw-r--r--MediaBrowser.Controller/Entities/IHasImages.cs6
-rw-r--r--MediaBrowser.Controller/Entities/Movies/BoxSet.cs2
-rw-r--r--MediaBrowser.Controller/MediaBrowser.Controller.csproj5
-rw-r--r--MediaBrowser.Controller/Providers/BaseItemXmlParser.cs2
-rw-r--r--MediaBrowser.Controller/Providers/BaseMetadataProvider.cs268
-rw-r--r--MediaBrowser.Controller/Providers/BaseProviderInfo.cs51
-rw-r--r--MediaBrowser.Controller/Providers/IForcedProvider.cs10
-rw-r--r--MediaBrowser.Controller/Providers/IImageSaver.cs29
-rw-r--r--MediaBrowser.Controller/Providers/IMetadataProvider.cs5
-rw-r--r--MediaBrowser.Controller/Providers/IProviderManager.cs4
-rw-r--r--MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs21
-rw-r--r--MediaBrowser.Controller/Providers/ProviderRefreshStatus.cs22
-rw-r--r--MediaBrowser.Model/Dto/BaseItemDto.cs2
-rw-r--r--MediaBrowser.Model/Entities/LocationType.cs8
-rw-r--r--MediaBrowser.Model/Notifications/NotificationLevel.cs6
-rw-r--r--MediaBrowser.Providers/Genres/GenreMetadataService.cs8
-rw-r--r--MediaBrowser.Providers/Manager/ProviderManager.cs185
-rw-r--r--MediaBrowser.Providers/MediaBrowser.Providers.csproj1
-rw-r--r--MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs3
-rw-r--r--MediaBrowser.Providers/People/MovieDbPersonProvider.cs94
-rw-r--r--MediaBrowser.Providers/Savers/XmlSaverHelpers.cs5
-rw-r--r--MediaBrowser.Providers/Xbmc/XbmcImageSaver.cs272
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs2
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs38
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs2
-rw-r--r--MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs3
-rw-r--r--MediaBrowser.ServerApplication/ApplicationHost.cs5
32 files changed, 594 insertions, 509 deletions
diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs
index 84f495efa..1eaf4acb1 100644
--- a/MediaBrowser.Api/ItemUpdateService.cs
+++ b/MediaBrowser.Api/ItemUpdateService.cs
@@ -5,7 +5,6 @@ using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Dto;
-using MediaBrowser.Model.Entities;
using ServiceStack;
using System;
using System.Linq;
@@ -94,8 +93,8 @@ namespace MediaBrowser.Api
{
var item = _dtoService.GetItemByDtoId(request.ItemId);
- var newEnableInternetProviders = request.EnableInternetProviders ?? true;
- var dontFetchMetaChanged = item.DontFetchMeta != !newEnableInternetProviders;
+ var newLockData = request.LockData ?? false;
+ var dontFetchMetaChanged = item.DontFetchMeta != newLockData;
UpdateItem(request, item);
@@ -107,7 +106,7 @@ namespace MediaBrowser.Api
foreach (var child in folder.RecursiveChildren.ToList())
{
- child.DontFetchMeta = !newEnableInternetProviders;
+ child.DontFetchMeta = newLockData;
await _libraryManager.UpdateItem(child, ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
}
}
@@ -307,16 +306,13 @@ namespace MediaBrowser.Api
{
hasAspectRatio.AspectRatio = request.AspectRatio;
}
-
- item.DontFetchMeta = !(request.EnableInternetProviders ?? true);
- if (request.EnableInternetProviders ?? true)
+
+ item.DontFetchMeta = (request.LockData ?? false);
+
+ if (request.LockedFields != null)
{
item.LockedFields = request.LockedFields;
}
- else
- {
- item.LockedFields.Clear();
- }
// Only allow this for series. Runtimes for media comes from ffprobe.
if (item is Series)
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 65e6c04b7..09b87bce9 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -240,6 +240,13 @@ namespace MediaBrowser.Api.Playback.Progressive
responseHeaders["Accept-Ranges"] = "none";
+ var length = response.Headers["Content-Length"];
+
+ if (!string.IsNullOrEmpty(length))
+ {
+ responseHeaders["Content-Length"] = length;
+ }
+
if (isHeadRequest)
{
using (response.Content)
@@ -273,13 +280,13 @@ namespace MediaBrowser.Api.Playback.Progressive
// Use the command line args with a dummy playlist path
var outputPath = GetOutputFilePath(state);
+ responseHeaders["Accept-Ranges"] = "none";
+
var contentType = MimeTypes.GetMimeType(outputPath);
// Headers only
if (isHeadRequest)
{
- responseHeaders["Accept-Ranges"] = "none";
-
return ResultFactory.GetResult(new byte[] { }, contentType, responseHeaders);
}
@@ -294,7 +301,6 @@ namespace MediaBrowser.Api.Playback.Progressive
var result = new ProgressiveStreamWriter(outputPath, Logger, FileSystem);
- result.Options["Accept-Ranges"] = "none";
result.Options["Content-Type"] = contentType;
// Add the response headers to the result object
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
index 2583450a3..27e164307 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicArtist.cs
@@ -179,7 +179,7 @@ namespace MediaBrowser.Controller.Entities.Audio
// Refresh all non-songs
foreach (var item in others)
{
- if (tasks.Count > 3)
+ if (tasks.Count >= 3)
{
await Task.WhenAll(tasks).ConfigureAwait(false);
tasks.Clear();
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 62ea0cf5d..224907a72 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -216,8 +216,18 @@ namespace MediaBrowser.Controller.Entities
/// Returns true if this item should not attempt to fetch metadata
/// </summary>
/// <value><c>true</c> if [dont fetch meta]; otherwise, <c>false</c>.</value>
+ [Obsolete("Please use IsLocked instead of DontFetchMeta")]
public bool DontFetchMeta { get; set; }
+ [IgnoreDataMember]
+ public bool IsLocked
+ {
+ get
+ {
+ return DontFetchMeta;
+ }
+ }
+
/// <summary>
/// Gets or sets the locked fields.
/// </summary>
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index c928a130e..c08a2ddf2 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -521,7 +521,7 @@ namespace MediaBrowser.Controller.Entities
foreach (var child in children)
{
- if (tasks.Count >= 4)
+ if (tasks.Count >= 3)
{
await Task.WhenAll(tasks).ConfigureAwait(false);
tasks.Clear();
diff --git a/MediaBrowser.Controller/Entities/IHasImages.cs b/MediaBrowser.Controller/Entities/IHasImages.cs
index e07db88c4..8e66605dd 100644
--- a/MediaBrowser.Controller/Entities/IHasImages.cs
+++ b/MediaBrowser.Controller/Entities/IHasImages.cs
@@ -148,6 +148,12 @@ namespace MediaBrowser.Controller.Entities
/// </summary>
/// <value><c>true</c> if this instance is in mixed folder; otherwise, <c>false</c>.</value>
bool IsInMixedFolder { get; }
+
+ /// <summary>
+ /// Gets a value indicating whether this instance is locked.
+ /// </summary>
+ /// <value><c>true</c> if this instance is locked; otherwise, <c>false</c>.</value>
+ bool IsLocked { get; }
}
public static class HasImagesExtensions
diff --git a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
index 3fd2af091..6cd078677 100644
--- a/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
+++ b/MediaBrowser.Controller/Entities/Movies/BoxSet.cs
@@ -99,7 +99,7 @@ namespace MediaBrowser.Controller.Entities.Movies
// Refresh songs
foreach (var item in items)
{
- if (tasks.Count >= 4)
+ if (tasks.Count >= 3)
{
await Task.WhenAll(tasks).ConfigureAwait(false);
tasks.Clear();
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index b62492bfe..32f2d151d 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -147,9 +147,11 @@
<Compile Include="Persistence\MediaStreamQuery.cs" />
<Compile Include="Providers\DirectoryService.cs" />
<Compile Include="Providers\ICustomMetadataProvider.cs" />
+ <Compile Include="Providers\IForcedProvider.cs" />
<Compile Include="Providers\IHasChangeMonitor.cs" />
<Compile Include="Entities\IHasMetadata.cs" />
<Compile Include="Providers\IImageProvider.cs" />
+ <Compile Include="Providers\IImageSaver.cs" />
<Compile Include="Providers\ILocalMetadataProvider.cs" />
<Compile Include="Providers\IProviderRepository.cs" />
<Compile Include="Providers\IRemoteImageProvider.cs" />
@@ -216,7 +218,7 @@
<Compile Include="Plugins\IPluginConfigurationPage.cs" />
<Compile Include="Plugins\IServerEntryPoint.cs" />
<Compile Include="Providers\IImageEnhancer.cs" />
- <Compile Include="Providers\BaseProviderInfo.cs" />
+ <Compile Include="Providers\ProviderRefreshStatus.cs" />
<Compile Include="Resolvers\IResolverIgnoreRule.cs" />
<Compile Include="Resolvers\EntityResolutionHelper.cs" />
<Compile Include="Resolvers\ResolverPriority.cs" />
@@ -224,7 +226,6 @@
<Compile Include="Library\ItemResolveArgs.cs" />
<Compile Include="IO\FileData.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Providers\BaseMetadataProvider.cs" />
<Compile Include="Session\ISessionController.cs" />
<Compile Include="Session\ISessionControllerFactory.cs" />
<Compile Include="Session\PlaybackInfo.cs" />
diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index 59b7cd8db..ada0aa6e2 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -719,7 +719,7 @@ namespace MediaBrowser.Controller.Providers
}
break;
}
- case "TvRageId":
+ case "TVRageId":
{
var id = reader.ReadElementContentAsString();
if (!string.IsNullOrWhiteSpace(id))
diff --git a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs b/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
deleted file mode 100644
index f8580244a..000000000
--- a/MediaBrowser.Controller/Providers/BaseMetadataProvider.cs
+++ /dev/null
@@ -1,268 +0,0 @@
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Entities;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Logging;
-using System;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Controller.Providers
-{
- /// <summary>
- /// Class BaseMetadataProvider
- /// </summary>
- public abstract class BaseMetadataProvider
- {
- /// <summary>
- /// Gets the logger.
- /// </summary>
- /// <value>The logger.</value>
- protected ILogger Logger { get; set; }
-
- protected ILogManager LogManager { get; set; }
-
- /// <summary>
- /// Gets the configuration manager.
- /// </summary>
- /// <value>The configuration manager.</value>
- protected IServerConfigurationManager ConfigurationManager { get; private set; }
-
- /// <summary>
- /// The _id
- /// </summary>
- public readonly Guid Id;
-
- /// <summary>
- /// The true task result
- /// </summary>
- protected static readonly Task<bool> TrueTaskResult = Task.FromResult(true);
-
- protected static readonly Task<bool> FalseTaskResult = Task.FromResult(false);
-
- /// <summary>
- /// Supportses the specified item.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- public abstract bool Supports(BaseItem item);
-
- /// <summary>
- /// Gets a value indicating whether [requires internet].
- /// </summary>
- /// <value><c>true</c> if [requires internet]; otherwise, <c>false</c>.</value>
- public virtual bool RequiresInternet
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Gets the provider version.
- /// </summary>
- /// <value>The provider version.</value>
- protected virtual string ProviderVersion
- {
- get
- {
- return null;
- }
- }
-
- public virtual ItemUpdateType ItemUpdateType
- {
- get { return RequiresInternet ? ItemUpdateType.MetadataDownload : ItemUpdateType.MetadataImport; }
- }
-
- /// <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 virtual bool RefreshOnVersionChange
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Determines if this provider is relatively slow and, therefore, should be skipped
- /// in certain instances. Default is whether or not it requires internet. Can be overridden
- /// for explicit designation.
- /// </summary>
- /// <value><c>true</c> if this instance is slow; otherwise, <c>false</c>.</value>
- public virtual bool IsSlow
- {
- get { return RequiresInternet; }
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="BaseMetadataProvider" /> class.
- /// </summary>
- protected BaseMetadataProvider(ILogManager logManager, IServerConfigurationManager configurationManager)
- {
- Logger = logManager.GetLogger(GetType().Name);
- LogManager = logManager;
- ConfigurationManager = configurationManager;
- Id = GetType().FullName.GetMD5();
-
- Initialize();
- }
-
- /// <summary>
- /// Initializes this instance.
- /// </summary>
- protected virtual void Initialize()
- {
- }
-
- /// <summary>
- /// Sets the persisted last refresh date on the item for this provider.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="value">The value.</param>
- /// <param name="providerVersion">The provider version.</param>
- /// <param name="providerInfo">The provider information.</param>
- /// <param name="status">The status.</param>
- /// <exception cref="System.ArgumentNullException">item</exception>
- public virtual void SetLastRefreshed(BaseItem item, DateTime value, string providerVersion,
- BaseProviderInfo providerInfo, ProviderRefreshStatus status = ProviderRefreshStatus.Success)
- {
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
-
- providerInfo.LastRefreshed = value;
- providerInfo.LastRefreshStatus = status;
- providerInfo.ProviderVersion = providerVersion;
- }
-
- /// <summary>
- /// Sets the last refreshed.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="value">The value.</param>
- /// <param name="providerInfo">The provider information.</param>
- /// <param name="status">The status.</param>
- public void SetLastRefreshed(BaseItem item, DateTime value,
- BaseProviderInfo providerInfo, ProviderRefreshStatus status = ProviderRefreshStatus.Success)
- {
- SetLastRefreshed(item, value, ProviderVersion, providerInfo, status);
- }
-
- /// <summary>
- /// Returns whether or not this provider should be re-fetched. Default functionality can
- /// compare a provided date with a last refresh time. This can be overridden for more complex
- /// determinations.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public bool NeedsRefresh(BaseItem item, BaseProviderInfo data)
- {
- if (item == null)
- {
- throw new ArgumentNullException();
- }
-
- return NeedsRefreshInternal(item, data);
- }
-
- /// <summary>
- /// Gets a value indicating whether [enforce dont fetch metadata].
- /// </summary>
- /// <value><c>true</c> if [enforce dont fetch metadata]; otherwise, <c>false</c>.</value>
- public virtual bool EnforceDontFetchMetadata
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Needses the refresh internal.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="providerInfo">The provider info.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- protected virtual bool NeedsRefreshInternal(BaseItem item, BaseProviderInfo providerInfo)
- {
- if (item == null)
- {
- throw new ArgumentNullException("item");
- }
-
- if (providerInfo == null)
- {
- throw new ArgumentNullException("providerInfo");
- }
-
- if (providerInfo.LastRefreshed == default(DateTime))
- {
- return true;
- }
-
- if (NeedsRefreshBasedOnCompareDate(item, providerInfo))
- {
- return true;
- }
-
- if (RefreshOnVersionChange && !String.Equals(ProviderVersion, providerInfo.ProviderVersion))
- {
- return true;
- }
-
- if (providerInfo.LastRefreshStatus != ProviderRefreshStatus.Success)
- {
- return true;
- }
-
- return false;
- }
-
- /// <summary>
- /// Needses the refresh based on compare date.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="providerInfo">The provider info.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
- protected virtual bool NeedsRefreshBasedOnCompareDate(BaseItem item, BaseProviderInfo providerInfo)
- {
- return CompareDate(item) > providerInfo.LastRefreshed;
- }
-
- /// <summary>
- /// Override this to return the date that should be compared to the last refresh date
- /// to determine if this provider should be re-fetched.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <returns>DateTime.</returns>
- protected virtual DateTime CompareDate(BaseItem item)
- {
- return DateTime.MinValue.AddMinutes(1); // want this to be greater than mindate so new items will refresh
- }
-
- /// <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>
- /// <exception cref="System.ArgumentNullException"></exception>
- public abstract Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken);
-
- /// <summary>
- /// Gets the priority.
- /// </summary>
- /// <value>The priority.</value>
- public abstract MetadataProviderPriority Priority { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs b/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
deleted file mode 100644
index 3a33924f0..000000000
--- a/MediaBrowser.Controller/Providers/BaseProviderInfo.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Providers
-{
- /// <summary>
- /// Class BaseProviderInfo
- /// </summary>
- public class BaseProviderInfo
- {
- public Guid ProviderId { get; set; }
- /// <summary>
- /// Gets or sets the last refreshed.
- /// </summary>
- /// <value>The last refreshed.</value>
- public DateTime LastRefreshed { get; set; }
- /// <summary>
- /// Gets or sets the file system stamp.
- /// </summary>
- /// <value>The file system stamp.</value>
- public Guid FileStamp { get; set; }
- /// <summary>
- /// Gets or sets the last refresh status.
- /// </summary>
- /// <value>The last refresh status.</value>
- public ProviderRefreshStatus LastRefreshStatus { get; set; }
- /// <summary>
- /// Gets or sets the provider version.
- /// </summary>
- /// <value>The provider version.</value>
- public string ProviderVersion { get; set; }
- }
-
- /// <summary>
- /// Enum ProviderRefreshStatus
- /// </summary>
- public enum ProviderRefreshStatus
- {
- /// <summary>
- /// The success
- /// </summary>
- Success = 0,
- /// <summary>
- /// The completed with errors
- /// </summary>
- CompletedWithErrors = 1,
- /// <summary>
- /// The failure
- /// </summary>
- Failure = 2
- }
-}
diff --git a/MediaBrowser.Controller/Providers/IForcedProvider.cs b/MediaBrowser.Controller/Providers/IForcedProvider.cs
new file mode 100644
index 000000000..9e35b00ad
--- /dev/null
+++ b/MediaBrowser.Controller/Providers/IForcedProvider.cs
@@ -0,0 +1,10 @@
+
+namespace MediaBrowser.Controller.Providers
+{
+ /// <summary>
+ /// This is a marker interface that will cause a provider to run even if IsLocked=true
+ /// </summary>
+ public interface IForcedProvider
+ {
+ }
+}
diff --git a/MediaBrowser.Controller/Providers/IImageSaver.cs b/MediaBrowser.Controller/Providers/IImageSaver.cs
new file mode 100644
index 000000000..5516c08f6
--- /dev/null
+++ b/MediaBrowser.Controller/Providers/IImageSaver.cs
@@ -0,0 +1,29 @@
+using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Model.Entities;
+using System.Collections.Generic;
+
+namespace MediaBrowser.Controller.Providers
+{
+ public interface IImageSaver
+ {
+ /// <summary>
+ /// Gets the name.
+ /// </summary>
+ /// <value>The name.</value>
+ string Name { get; }
+ }
+
+ public interface IImageFileSaver : IImageSaver
+ {
+ /// <summary>
+ /// Gets the save paths.
+ /// </summary>
+ /// <param name="item">The item.</param>
+ /// <param name="type">The type.</param>
+ /// <param name="format">The format.</param>
+ /// <param name="index">The index.</param>
+ /// <returns>IEnumerable{System.String}.</returns>
+ IEnumerable<string> GetSavePaths(IHasImages item, ImageType type, ImageFormat format, int index);
+ }
+}
diff --git a/MediaBrowser.Controller/Providers/IMetadataProvider.cs b/MediaBrowser.Controller/Providers/IMetadataProvider.cs
index 70bc06059..d33b2c9eb 100644
--- a/MediaBrowser.Controller/Providers/IMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/IMetadataProvider.cs
@@ -1,5 +1,4 @@
-using System;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Providers
{
@@ -26,10 +25,8 @@ namespace MediaBrowser.Controller.Providers
}
public class MetadataResult<T>
- where T : IHasMetadata
{
public bool HasMetadata { get; set; }
public T Item { get; set; }
}
-
}
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index 4aeb86a6a..eb4d3d9a6 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -55,8 +55,10 @@ namespace MediaBrowser.Controller.Providers
/// <param name="metadataServices">The metadata services.</param>
/// <param name="metadataProviders">The metadata providers.</param>
/// <param name="savers">The savers.</param>
+ /// <param name="imageSavers">The image savers.</param>
void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders,
- IEnumerable<IMetadataSaver> savers);
+ IEnumerable<IMetadataSaver> savers,
+ IEnumerable<IImageSaver> imageSavers);
/// <summary>
/// Gets the available remote images.
diff --git a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs
index cbbd62557..065017cce 100644
--- a/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs
+++ b/MediaBrowser.Controller/Providers/IRemoteMetadataProvider.cs
@@ -1,6 +1,7 @@
-using System.Threading;
+using MediaBrowser.Controller.Entities;
+using System.Collections.Generic;
+using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Entities;
namespace MediaBrowser.Controller.Providers
{
@@ -8,10 +9,24 @@ namespace MediaBrowser.Controller.Providers
{
}
- public interface IRemoteMetadataProvider<TItemType, in TLookupInfoType> : IMetadataProvider<TItemType>, IRemoteMetadataProvider
+ public interface IRemoteMetadataProvider<TItemType, TLookupInfoType> : IMetadataProvider<TItemType>, IRemoteMetadataProvider
where TItemType : IHasMetadata, IHasLookupInfo<TLookupInfoType>
where TLookupInfoType : ItemLookupInfo, new()
{
Task<MetadataResult<TItemType>> GetMetadata(TLookupInfoType info, CancellationToken cancellationToken);
}
+
+ public interface IRemoteSearchProvider<TLookupInfoType>
+ where TLookupInfoType : ItemLookupInfo
+ {
+ Task<IEnumerable<SearchResult<TLookupInfoType>>> GetSearchResults(TLookupInfoType searchInfo, CancellationToken cancellationToken);
+ }
+
+ public class SearchResult<T>
+ where T : ItemLookupInfo
+ {
+ public T Item { get; set; }
+
+ public string ImageUrl { get; set; }
+ }
}
diff --git a/MediaBrowser.Controller/Providers/ProviderRefreshStatus.cs b/MediaBrowser.Controller/Providers/ProviderRefreshStatus.cs
new file mode 100644
index 000000000..6523dc417
--- /dev/null
+++ b/MediaBrowser.Controller/Providers/ProviderRefreshStatus.cs
@@ -0,0 +1,22 @@
+
+namespace MediaBrowser.Controller.Providers
+{
+ /// <summary>
+ /// Enum ProviderRefreshStatus
+ /// </summary>
+ public enum ProviderRefreshStatus
+ {
+ /// <summary>
+ /// The success
+ /// </summary>
+ Success = 0,
+ /// <summary>
+ /// The completed with errors
+ /// </summary>
+ CompletedWithErrors = 1,
+ /// <summary>
+ /// The failure
+ /// </summary>
+ Failure = 2
+ }
+}
diff --git a/MediaBrowser.Model/Dto/BaseItemDto.cs b/MediaBrowser.Model/Dto/BaseItemDto.cs
index 566c136b7..8f4330446 100644
--- a/MediaBrowser.Model/Dto/BaseItemDto.cs
+++ b/MediaBrowser.Model/Dto/BaseItemDto.cs
@@ -657,7 +657,7 @@ namespace MediaBrowser.Model.Dto
/// Gets or sets a value indicating whether [enable internet providers].
/// </summary>
/// <value><c>true</c> if [enable internet providers]; otherwise, <c>false</c>.</value>
- public bool? EnableInternetProviders { get; set; }
+ public bool? LockData { get; set; }
/// <summary>
/// Gets a value indicating whether this instance can resume.
diff --git a/MediaBrowser.Model/Entities/LocationType.cs b/MediaBrowser.Model/Entities/LocationType.cs
index 09c0b20ca..84de803aa 100644
--- a/MediaBrowser.Model/Entities/LocationType.cs
+++ b/MediaBrowser.Model/Entities/LocationType.cs
@@ -9,18 +9,18 @@ namespace MediaBrowser.Model.Entities
/// <summary>
/// The file system
/// </summary>
- FileSystem = 1,
+ FileSystem = 0,
/// <summary>
/// The remote
/// </summary>
- Remote = 2,
+ Remote = 1,
/// <summary>
/// The virtual
/// </summary>
- Virtual = 3,
+ Virtual = 2,
/// <summary>
/// The offline
/// </summary>
- Offline = 4
+ Offline = 3
}
}
diff --git a/MediaBrowser.Model/Notifications/NotificationLevel.cs b/MediaBrowser.Model/Notifications/NotificationLevel.cs
index c7e68b163..a49ee2fe6 100644
--- a/MediaBrowser.Model/Notifications/NotificationLevel.cs
+++ b/MediaBrowser.Model/Notifications/NotificationLevel.cs
@@ -3,8 +3,8 @@ namespace MediaBrowser.Model.Notifications
{
public enum NotificationLevel
{
- Normal = 1,
- Warning = 2,
- Error = 3
+ Normal = 0,
+ Warning = 1,
+ Error = 2
}
}
diff --git a/MediaBrowser.Providers/Genres/GenreMetadataService.cs b/MediaBrowser.Providers/Genres/GenreMetadataService.cs
index b19241095..f408d026b 100644
--- a/MediaBrowser.Providers/Genres/GenreMetadataService.cs
+++ b/MediaBrowser.Providers/Genres/GenreMetadataService.cs
@@ -1,25 +1,19 @@
using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
-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.Genres
{
public class GenreMetadataService : MetadataService<Genre, ItemLookupInfo>
{
- private readonly ILibraryManager _libraryManager;
-
- public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem, ILibraryManager libraryManager)
+ public GenreMetadataService(IServerConfigurationManager serverConfigurationManager, ILogger logger, IProviderManager providerManager, IProviderRepository providerRepo, IFileSystem fileSystem)
: base(serverConfigurationManager, logger, providerManager, providerRepo, fileSystem)
{
- _libraryManager = libraryManager;
}
/// <summary>
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index ced9e4868..19d1e3ba2 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -52,11 +52,10 @@ namespace MediaBrowser.Providers.Manager
private readonly IFileSystem _fileSystem;
- private readonly IProviderRepository _providerRepo;
-
private IMetadataService[] _metadataServices = { };
private IMetadataProvider[] _metadataProviders = { };
private IEnumerable<IMetadataSaver> _savers;
+ private IImageSaver[] _imageSavers;
/// <summary>
/// Initializes a new instance of the <see cref="ProviderManager" /> class.
@@ -66,15 +65,13 @@ namespace MediaBrowser.Providers.Manager
/// <param name="libraryMonitor">The directory watchers.</param>
/// <param name="logManager">The log manager.</param>
/// <param name="fileSystem">The file system.</param>
- /// <param name="providerRepo">The provider repo.</param>
- public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem, IProviderRepository providerRepo)
+ public ProviderManager(IHttpClient httpClient, IServerConfigurationManager configurationManager, ILibraryMonitor libraryMonitor, ILogManager logManager, IFileSystem fileSystem)
{
_logger = logManager.GetLogger("ProviderManager");
_httpClient = httpClient;
ConfigurationManager = configurationManager;
_libraryMonitor = libraryMonitor;
_fileSystem = fileSystem;
- _providerRepo = providerRepo;
}
/// <summary>
@@ -84,13 +81,16 @@ namespace MediaBrowser.Providers.Manager
/// <param name="metadataServices">The metadata services.</param>
/// <param name="metadataProviders">The metadata providers.</param>
/// <param name="metadataSavers">The metadata savers.</param>
- public void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders, IEnumerable<IMetadataSaver> metadataSavers)
+ /// <param name="imageSavers">The image savers.</param>
+ public void AddParts(IEnumerable<IImageProvider> imageProviders, IEnumerable<IMetadataService> metadataServices, IEnumerable<IMetadataProvider> metadataProviders, IEnumerable<IMetadataSaver> metadataSavers,
+ IEnumerable<IImageSaver> imageSavers)
{
ImageProviders = imageProviders.ToArray();
_metadataServices = metadataServices.OrderBy(i => i.Order).ToArray();
_metadataProviders = metadataProviders.ToArray();
_savers = metadataSavers.ToArray();
+ _imageSavers = imageSavers.ToArray();
}
public Task RefreshMetadata(IHasMetadata item, MetadataRefreshOptions options, CancellationToken cancellationToken)
@@ -107,62 +107,6 @@ namespace MediaBrowser.Providers.Manager
}
/// <summary>
- /// Saves to library filesystem.
- /// </summary>
- /// <param name="item">The item.</param>
- /// <param name="path">The path.</param>
- /// <param name="dataToSave">The data to save.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
- /// <returns>Task.</returns>
- /// <exception cref="System.ArgumentNullException"></exception>
- public async Task SaveToLibraryFilesystem(BaseItem item, string path, Stream dataToSave, CancellationToken cancellationToken)
- {
- if (item == null)
- {
- throw new ArgumentNullException();
- }
- if (string.IsNullOrEmpty(path))
- {
- throw new ArgumentNullException();
- }
- if (dataToSave == null)
- {
- throw new ArgumentNullException();
- }
-
- if (cancellationToken.IsCancellationRequested)
- {
- dataToSave.Dispose();
- cancellationToken.ThrowIfCancellationRequested();
- }
-
- //Tell the watchers to ignore
- _libraryMonitor.ReportFileSystemChangeBeginning(path);
-
- if (dataToSave.CanSeek)
- {
- dataToSave.Position = 0;
- }
-
- try
- {
- using (dataToSave)
- {
- using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
- {
- await dataToSave.CopyToAsync(fs, StreamDefaults.DefaultCopyToBufferSize, cancellationToken).ConfigureAwait(false);
- }
- }
- }
- finally
- {
- //Remove the ignore
- _libraryMonitor.ReportFileSystemChangeComplete(path, false);
- }
- }
-
-
- /// <summary>
/// Saves the image.
/// </summary>
/// <param name="item">The item.</param>
@@ -252,8 +196,13 @@ namespace MediaBrowser.Providers.Manager
result = result.Where(i => i.Type == type.Value);
}
- return string.IsNullOrEmpty(preferredLanguage) ? result :
- FilterImages(result, preferredLanguage);
+ if (string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase))
+ {
+ result = result.Where(i => string.IsNullOrEmpty(i.Language) ||
+ string.Equals(i.Language, "en", StringComparison.OrdinalIgnoreCase));
+ }
+
+ return result;
}
catch (Exception ex)
{
@@ -262,17 +211,6 @@ namespace MediaBrowser.Providers.Manager
}
}
- private IEnumerable<RemoteImageInfo> FilterImages(IEnumerable<RemoteImageInfo> images, string preferredLanguage)
- {
- if (string.Equals(preferredLanguage, "en", StringComparison.OrdinalIgnoreCase))
- {
- images = images.Where(i => string.IsNullOrEmpty(i.Language) ||
- string.Equals(i.Language, "en", StringComparison.OrdinalIgnoreCase));
- }
-
- return images;
- }
-
/// <summary>
/// Gets the supported image providers.
/// </summary>
@@ -294,13 +232,16 @@ namespace MediaBrowser.Providers.Manager
private IEnumerable<IImageProvider> GetImageProviders(IHasImages item, MetadataOptions options, bool includeDisabled)
{
+ // Avoid implicitly captured closure
+ var currentOptions = options;
+
return ImageProviders.Where(i => CanRefresh(i, item, options, includeDisabled))
.OrderBy(i =>
{
// See if there's a user-defined order
if (!(i is ILocalImageProvider))
{
- var index = Array.IndexOf(options.ImageFetcherOrder, i.Name);
+ var index = Array.IndexOf(currentOptions.ImageFetcherOrder, i.Name);
if (index != -1)
{
@@ -325,36 +266,13 @@ namespace MediaBrowser.Providers.Manager
private IEnumerable<IMetadataProvider<T>> GetMetadataProvidersInternal<T>(IHasMetadata item, MetadataOptions options, bool includeDisabled)
where T : IHasMetadata
{
- return _metadataProviders.OfType<IMetadataProvider<T>>()
- .Where(i => CanRefresh(i, item, options, includeDisabled))
- .OrderBy(i =>
- {
- // See if there's a user-defined order
- if (i is ILocalMetadataProvider)
- {
- var index = Array.IndexOf(options.LocalMetadataReaderOrder, i.Name);
-
- if (index != -1)
- {
- return index;
- }
- }
-
- // See if there's a user-defined order
- if (i is IRemoteMetadataProvider)
- {
- var index = Array.IndexOf(options.MetadataFetcherOrder, i.Name);
-
- if (index != -1)
- {
- return index;
- }
- }
+ // Avoid implicitly captured closure
+ var currentOptions = options;
- // Not configured. Just return some high number to put it at the end.
- return 100;
- })
- .ThenBy(GetOrder);
+ return _metadataProviders.OfType<IMetadataProvider<T>>()
+ .Where(i => CanRefresh(i, item, currentOptions, includeDisabled))
+ .OrderBy(i => GetConfiguredOrder(i, options))
+ .ThenBy(GetDefaultOrder);
}
private IEnumerable<IRemoteImageProvider> GetRemoteImageProviders(IHasImages item, bool includeDisabled)
@@ -368,6 +286,12 @@ namespace MediaBrowser.Providers.Manager
{
if (!includeDisabled)
{
+ // If locked only allow local providers
+ if (item.IsLocked && !(provider is ILocalMetadataProvider) && !(provider is IForcedProvider))
+ {
+ return false;
+ }
+
if (provider is IRemoteMetadataProvider)
{
if (Array.IndexOf(options.DisabledMetadataFetchers, provider.Name) != -1)
@@ -398,6 +322,12 @@ namespace MediaBrowser.Providers.Manager
{
if (!includeDisabled)
{
+ // If locked only allow local providers
+ if (item.IsLocked && !(provider is ILocalImageProvider))
+ {
+ return false;
+ }
+
if (provider is IRemoteImageProvider)
{
if (Array.IndexOf(options.DisabledImageFetchers, provider.Name) != -1)
@@ -440,12 +370,35 @@ namespace MediaBrowser.Providers.Manager
return hasOrder.Order;
}
- /// <summary>
- /// Gets the order.
- /// </summary>
- /// <param name="provider">The provider.</param>
- /// <returns>System.Int32.</returns>
- private int GetOrder(IMetadataProvider provider)
+ private int GetConfiguredOrder(IMetadataProvider provider, MetadataOptions options)
+ {
+ // See if there's a user-defined order
+ if (provider is ILocalMetadataProvider)
+ {
+ var index = Array.IndexOf(options.LocalMetadataReaderOrder, provider.Name);
+
+ if (index != -1)
+ {
+ return index;
+ }
+ }
+
+ // See if there's a user-defined order
+ if (provider is IRemoteMetadataProvider)
+ {
+ var index = Array.IndexOf(options.MetadataFetcherOrder, provider.Name);
+
+ if (index != -1)
+ {
+ return index;
+ }
+ }
+
+ // Not configured. Just return some high number to put it at the end.
+ return 100;
+ }
+
+ private int GetDefaultOrder(IMetadataProvider provider)
{
var hasOrder = provider as IHasOrder;
@@ -578,6 +531,7 @@ namespace MediaBrowser.Providers.Manager
}
private readonly ConcurrentDictionary<string, SemaphoreSlim> _fileLocks = new ConcurrentDictionary<string, SemaphoreSlim>();
+
/// <summary>
/// Saves the metadata.
/// </summary>
@@ -658,5 +612,14 @@ namespace MediaBrowser.Providers.Manager
return false;
}
}
+
+ //private IEnumerable<TLookupType> GetRemoteSearchResults<TLookupType>(TLookupType searchInfo,
+ // CancellationToken cancellationToken)
+ // where TLookupType : ItemLookupInfo
+ //{
+ // var providers = _metadataProviders.OfType<IRemoteSearchProvider<TLookupType>>();
+
+
+ //}
}
} \ No newline at end of file
diff --git a/MediaBrowser.Providers/MediaBrowser.Providers.csproj b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
index 3a7fcd918..724a60b97 100644
--- a/MediaBrowser.Providers/MediaBrowser.Providers.csproj
+++ b/MediaBrowser.Providers/MediaBrowser.Providers.csproj
@@ -198,6 +198,7 @@
<Compile Include="TV\TvdbPrescanTask.cs" />
<Compile Include="Users\UserMetadataService.cs" />
<Compile Include="Videos\VideoMetadataService.cs" />
+ <Compile Include="Xbmc\XbmcImageSaver.cs" />
<Compile Include="Years\YearMetadataService.cs" />
</ItemGroup>
<ItemGroup>
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index 7ac48655a..161532fd3 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -31,7 +31,8 @@ namespace MediaBrowser.Providers.MediaInfo
ICustomMetadataProvider<Video>,
ICustomMetadataProvider<Audio>,
IHasChangeMonitor,
- IHasOrder
+ IHasOrder,
+ IForcedProvider
{
private readonly ILogger _logger;
private readonly IIsoManager _isoManager;
diff --git a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
index f439f4bc5..5691190dc 100644
--- a/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
+++ b/MediaBrowser.Providers/People/MovieDbPersonProvider.cs
@@ -12,6 +12,7 @@ using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
+using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
@@ -21,9 +22,9 @@ namespace MediaBrowser.Providers.People
public class MovieDbPersonProvider : IRemoteMetadataProvider<Person, PersonLookupInfo>
{
const string DataFileName = "info.json";
-
+
internal static MovieDbPersonProvider Current { get; private set; }
-
+
private readonly IJsonSerializer _jsonSerializer;
private readonly IFileSystem _fileSystem;
private readonly IServerConfigurationManager _configurationManager;
@@ -41,6 +42,73 @@ namespace MediaBrowser.Providers.People
get { return "TheMovieDb"; }
}
+ public async Task<IEnumerable<SearchResult<PersonLookupInfo>>> GetSearchResults(PersonLookupInfo searchInfo, CancellationToken cancellationToken)
+ {
+ var tmdbId = searchInfo.GetProviderId(MetadataProviders.Tmdb);
+
+ var tmdbSettings = await MovieDbProvider.Current.GetTmdbSettings(cancellationToken).ConfigureAwait(false);
+
+ var tmdbImageUrl = tmdbSettings.images.base_url + "original";
+
+ if (!string.IsNullOrEmpty(tmdbId))
+ {
+ await EnsurePersonInfo(tmdbId, cancellationToken).ConfigureAwait(false);
+
+ var dataFilePath = GetPersonDataFilePath(_configurationManager.ApplicationPaths, tmdbId);
+ var info = _jsonSerializer.DeserializeFromFile<PersonResult>(dataFilePath);
+
+ var images = (info.images ?? new Images()).profiles ?? new List<Profile>();
+
+ var result = new SearchResult<PersonLookupInfo>
+ {
+ Item = new PersonLookupInfo
+ {
+ Name = info.name
+ },
+
+ ImageUrl = images.Count == 0 ? null : (tmdbImageUrl + images[0].file_path)
+ };
+
+ result.Item.SetProviderId(MetadataProviders.Tmdb, info.id.ToString(_usCulture));
+ result.Item.SetProviderId(MetadataProviders.Imdb, info.imdb_id.ToString(_usCulture));
+
+ return new[] { result };
+ }
+
+ var url = string.Format(@"http://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(searchInfo.Name), MovieDbProvider.ApiKey);
+
+ using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
+ {
+ Url = url,
+ CancellationToken = cancellationToken,
+ AcceptHeader = MovieDbProvider.AcceptHeader
+
+ }).ConfigureAwait(false))
+ {
+ var result = _jsonSerializer.DeserializeFromStream<PersonSearchResults>(json) ??
+ new PersonSearchResults();
+
+ return result.Results.Select(i => GetSearchResult(i, tmdbImageUrl));
+ }
+ }
+
+ private SearchResult<PersonLookupInfo> GetSearchResult(PersonSearchResult i, string baseImageUrl)
+ {
+ var result = new SearchResult<PersonLookupInfo>
+ {
+ Item = new PersonLookupInfo
+ {
+ Name = i.Name
+ },
+
+ ImageUrl = string.IsNullOrEmpty(i.Profile_Path) ? null : (baseImageUrl + i.Profile_Path)
+ };
+
+ result.Item.SetProviderId(MetadataProviders.Tmdb, i.Id.ToString(_usCulture));
+
+ return result;
+ }
+
public async Task<MetadataResult<Person>> GetMetadata(PersonLookupInfo id, CancellationToken cancellationToken)
{
var tmdbId = id.GetProviderId(MetadataProviders.Tmdb);
@@ -48,7 +116,7 @@ namespace MediaBrowser.Providers.People
// We don't already have an Id, need to fetch it
if (string.IsNullOrEmpty(tmdbId))
{
- tmdbId = await GetTmdbId(id.Name, cancellationToken).ConfigureAwait(false);
+ tmdbId = await GetTmdbId(id, cancellationToken).ConfigureAwait(false);
}
var result = new MetadataResult<Person>();
@@ -100,26 +168,14 @@ namespace MediaBrowser.Providers.People
/// <summary>
/// Gets the TMDB id.
/// </summary>
- /// <param name="name">The name.</param>
+ /// <param name="info">The information.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{System.String}.</returns>
- private async Task<string> GetTmdbId(string name, CancellationToken cancellationToken)
+ private async Task<string> GetTmdbId(PersonLookupInfo info, CancellationToken cancellationToken)
{
- string url = string.Format(@"http://api.themoviedb.org/3/search/person?api_key={1}&query={0}", WebUtility.UrlEncode(name), MovieDbProvider.ApiKey);
- PersonSearchResults searchResult = null;
-
- using (var json = await MovieDbProvider.Current.GetMovieDbResponse(new HttpRequestOptions
- {
- Url = url,
- CancellationToken = cancellationToken,
- AcceptHeader = MovieDbProvider.AcceptHeader
-
- }).ConfigureAwait(false))
- {
- searchResult = _jsonSerializer.DeserializeFromStream<PersonSearchResults>(json);
- }
+ var results = await GetSearchResults(info, cancellationToken).ConfigureAwait(false);
- return searchResult != null && searchResult.Total_Results > 0 ? searchResult.Results[0].Id.ToString(_usCulture) : null;
+ return results.Select(i => i.Item.GetProviderId(MetadataProviders.Tmdb)).FirstOrDefault();
}
internal async Task EnsurePersonInfo(string id, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
index 6a3d7d837..eed91dfaa 100644
--- a/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.Providers/Savers/XmlSaverHelpers.cs
@@ -22,6 +22,8 @@ namespace MediaBrowser.Providers.Savers
"Added",
"AspectRatio",
+ "AudioDbAlbumId",
+ "AudioDbArtistId",
"AwardSummary",
"BirthDate",
"Budget",
@@ -73,6 +75,7 @@ namespace MediaBrowser.Providers.Savers
"TVcomId",
"TvDbId",
"Type",
+ "TVRageId",
"VoteCount",
"Website",
"Zap2ItId"
@@ -477,7 +480,7 @@ namespace MediaBrowser.Providers.Savers
if (!string.IsNullOrEmpty(externalId))
{
- builder.Append("<TvRageId>" + SecurityElement.Escape(externalId) + "</TvRageId>");
+ builder.Append("<TVRageId>" + SecurityElement.Escape(externalId) + "</TVRageId>");
}
var hasTagline = item as IHasTaglines;
diff --git a/MediaBrowser.Providers/Xbmc/XbmcImageSaver.cs b/MediaBrowser.Providers/Xbmc/XbmcImageSaver.cs
new file mode 100644
index 000000000..5a4408f1b
--- /dev/null
+++ b/MediaBrowser.Providers/Xbmc/XbmcImageSaver.cs
@@ -0,0 +1,272 @@
+using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Entities;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+
+namespace MediaBrowser.Providers.Xbmc
+{
+ public class XbmcImageSaver : IImageFileSaver
+ {
+ private readonly CultureInfo _usCulture = new CultureInfo("en-US");
+
+ public IEnumerable<string> GetSavePaths(IHasImages item, ImageType type, ImageFormat format, int index)
+ {
+ var season = item as Season;
+
+ if (!SupportsItem(item, type, season))
+ {
+ return new string[] { };
+ }
+
+ var extension = "." + format.ToString().ToLower();
+
+ // Backdrop paths
+ if (type == ImageType.Backdrop)
+ {
+ if (index == 0)
+ {
+ if (item.IsInMixedFolder)
+ {
+ return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart", extension) };
+ }
+
+ if (season != null && season.IndexNumber.HasValue)
+ {
+ var seriesFolder = season.SeriesPath;
+
+ var seasonMarker = season.IndexNumber.Value == 0
+ ? "-specials"
+ : season.IndexNumber.Value.ToString("00", _usCulture);
+
+ var imageFilename = "season" + seasonMarker + "-fanart" + extension;
+
+ return new[] { Path.Combine(seriesFolder, imageFilename) };
+ }
+
+ return new[]
+ {
+ Path.Combine(item.ContainingFolderPath, "fanart" + extension)
+ };
+ }
+
+ if (item.IsInMixedFolder)
+ {
+ return new[] { GetSavePathForItemInMixedFolder(item, type, "fanart" + index.ToString(_usCulture), extension) };
+ }
+
+ var extraFanartFilename = GetBackdropSaveFilename(item.GetImages(ImageType.Backdrop), "fanart", "fanart", index);
+
+ return new[]
+ {
+ Path.Combine(item.ContainingFolderPath, "extrafanart", extraFanartFilename + extension),
+ Path.Combine(item.ContainingFolderPath, "extrathumbs", "thumb" + index.ToString(_usCulture) + extension)
+ };
+ }
+
+ if (type == ImageType.Primary)
+ {
+ if (season != null && season.IndexNumber.HasValue)
+ {
+ var seriesFolder = season.SeriesPath;
+
+ var seasonMarker = season.IndexNumber.Value == 0
+ ? "-specials"
+ : season.IndexNumber.Value.ToString("00", _usCulture);
+
+ var imageFilename = "season" + seasonMarker + "-poster" + extension;
+
+ return new[] { Path.Combine(seriesFolder, imageFilename) };
+ }
+
+ if (item is Episode)
+ {
+ var seasonFolder = Path.GetDirectoryName(item.Path);
+
+ var imageFilename = Path.GetFileNameWithoutExtension(item.Path) + "-thumb" + extension;
+
+ return new[] { Path.Combine(seasonFolder, imageFilename) };
+ }
+
+ if (item.IsInMixedFolder || item is MusicVideo)
+ {
+ return new[] { GetSavePathForItemInMixedFolder(item, type, string.Empty, extension) };
+ }
+
+ if (item is MusicAlbum || item is MusicArtist)
+ {
+ return new[] { Path.Combine(item.ContainingFolderPath, "folder" + extension) };
+ }
+
+ return new[] { Path.Combine(item.ContainingFolderPath, "poster" + extension) };
+ }
+
+ if (type == ImageType.Banner)
+ {
+ if (season != null && season.IndexNumber.HasValue)
+ {
+ var seriesFolder = season.SeriesPath;
+
+ var seasonMarker = season.IndexNumber.Value == 0
+ ? "-specials"
+ : season.IndexNumber.Value.ToString("00", _usCulture);
+
+ var imageFilename = "season" + seasonMarker + "-banner" + extension;
+
+ return new[] { Path.Combine(seriesFolder, imageFilename) };
+ }
+ }
+
+ if (type == ImageType.Thumb)
+ {
+ if (season != null && season.IndexNumber.HasValue)
+ {
+ var seriesFolder = season.SeriesPath;
+
+ var seasonMarker = season.IndexNumber.Value == 0
+ ? "-specials"
+ : season.IndexNumber.Value.ToString("00", _usCulture);
+
+ var imageFilename = "season" + seasonMarker + "-landscape" + extension;
+
+ return new[] { Path.Combine(seriesFolder, imageFilename) };
+ }
+
+ if (item.IsInMixedFolder)
+ {
+ return new[] { GetSavePathForItemInMixedFolder(item, type, "landscape", extension) };
+ }
+
+ return new[] { Path.Combine(item.ContainingFolderPath, "landscape" + extension) };
+ }
+
+ return GetStandardSavePaths(item, type, index, extension);
+ }
+
+ private IEnumerable<string> GetStandardSavePaths(IHasImages item, ImageType type, int imageIndex, string extension)
+ {
+ string filename;
+
+ switch (type)
+ {
+ case ImageType.Art:
+ filename = "clearart";
+ break;
+ case ImageType.BoxRear:
+ filename = "back";
+ break;
+ case ImageType.Disc:
+ filename = item is MusicAlbum ? "cdart" : "disc";
+ break;
+ case ImageType.Screenshot:
+ filename = GetBackdropSaveFilename(item.GetImages(type), "screenshot", "screenshot", imageIndex);
+ break;
+ default:
+ filename = type.ToString().ToLower();
+ break;
+ }
+
+ string path = null;
+
+ if (item.IsInMixedFolder)
+ {
+ path = GetSavePathForItemInMixedFolder(item, type, filename, extension);
+ }
+
+ if (string.IsNullOrEmpty(path))
+ {
+ path = Path.Combine(item.ContainingFolderPath, filename + extension);
+ }
+
+ if (string.IsNullOrEmpty(path))
+ {
+ return new string[] { };
+ }
+
+ return new[] { path };
+ }
+
+
+ private string GetSavePathForItemInMixedFolder(IHasImages item, ImageType type, string imageFilename, string extension)
+ {
+ if (type == ImageType.Primary)
+ {
+ imageFilename = "poster";
+ }
+ var folder = Path.GetDirectoryName(item.Path);
+
+ return Path.Combine(folder, Path.GetFileNameWithoutExtension(item.Path) + "-" + imageFilename + extension);
+ }
+
+ private bool SupportsItem(IHasImages item, ImageType type, Season season)
+ {
+ if (item.IsOwnedItem || item is Audio || item is User)
+ {
+ return false;
+ }
+
+ if (type != ImageType.Primary && item is Episode)
+ {
+ return false;
+ }
+
+ if (!item.SupportsLocalMetadata)
+ {
+ return false;
+ }
+
+ var locationType = item.LocationType;
+ if (locationType == LocationType.Remote || locationType == LocationType.Virtual)
+ {
+ var allowSaving = false;
+
+ // If season is virtual under a physical series, save locally if using compatible convention
+ if (season != null)
+ {
+ var series = season.Series;
+
+ if (series != null && series.SupportsLocalMetadata)
+ {
+ allowSaving = true;
+ }
+ }
+
+ if (!allowSaving)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private string GetBackdropSaveFilename(IEnumerable<ItemImageInfo> images, string zeroIndexFilename, string numberedIndexPrefix, int? index)
+ {
+ if (index.HasValue && index.Value == 0)
+ {
+ return zeroIndexFilename;
+ }
+
+ var filenames = images.Select(i => Path.GetFileNameWithoutExtension(i.Path)).ToList();
+
+ var current = 1;
+ while (filenames.Contains(numberedIndexPrefix + current.ToString(_usCulture), StringComparer.OrdinalIgnoreCase))
+ {
+ current++;
+ }
+
+ return numberedIndexPrefix + current.ToString(_usCulture);
+ }
+
+ public string Name
+ {
+ get { return "MB3/Plex/Xbmc Images"; }
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index aba8c3353..65a496533 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -664,7 +664,7 @@ namespace MediaBrowser.Server.Implementations.Dto
if (fields.Contains(ItemFields.Settings))
{
dto.LockedFields = item.LockedFields;
- dto.EnableInternetProviders = !item.DontFetchMeta;
+ dto.LockData = item.DontFetchMeta;
}
var hasBudget = item as IHasBudget;
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
index 3712a58f5..4c21d2eb7 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpResultFactory.cs
@@ -435,10 +435,10 @@ namespace MediaBrowser.Server.Implementations.HttpServer
if (!compress || string.IsNullOrEmpty(requestedCompressionType))
{
- var stream = await factoryFn().ConfigureAwait(false);
-
var rangeHeader = requestContext.GetHeader("Range");
+ var stream = await factoryFn().ConfigureAwait(false);
+
if (!string.IsNullOrEmpty(rangeHeader))
{
return new RangeRequestWriter(rangeHeader, stream, contentType, isHeadRequest);
@@ -448,34 +448,54 @@ namespace MediaBrowser.Server.Implementations.HttpServer
if (isHeadRequest)
{
+ stream.Dispose();
+
return GetHttpResult(new byte[] { }, contentType);
}
return new StreamWriter(stream, contentType, _logger);
}
- if (isHeadRequest)
- {
- return GetHttpResult(new byte[] { }, contentType);
- }
-
string content;
+ long originalContentLength = 0;
using (var stream = await factoryFn().ConfigureAwait(false))
{
- using (var reader = new StreamReader(stream))
+ using (var memoryStream = new MemoryStream())
{
- content = await reader.ReadToEndAsync().ConfigureAwait(false);
+ await stream.CopyToAsync(memoryStream).ConfigureAwait(false);
+ memoryStream.Position = 0;
+
+ originalContentLength = memoryStream.Length;
+
+ using (var reader = new StreamReader(memoryStream))
+ {
+ content = await reader.ReadToEndAsync().ConfigureAwait(false);
+ }
}
}
if (!SupportsCompression)
{
+ responseHeaders["Content-Length"] = originalContentLength.ToString(UsCulture);
+
+ if (isHeadRequest)
+ {
+ return GetHttpResult(new byte[] { }, contentType);
+ }
+
return new HttpResult(content, contentType);
}
var contents = content.Compress(requestedCompressionType);
+ responseHeaders["Content-Length"] = contents.Length.ToString(UsCulture);
+
+ if (isHeadRequest)
+ {
+ return GetHttpResult(new byte[] { }, contentType);
+ }
+
return new CompressedResult(contents, requestedCompressionType, contentType);
}
diff --git a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs
index 520f03561..ac1621709 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/ResponseFilter.cs
@@ -69,7 +69,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
var response = (HttpListenerResponse)res.OriginalResponse;
response.ContentLength64 = length;
-
+
// Disable chunked encoding. Technically this is only needed when using Content-Range, but
// anytime we know the content length there's no need for it
response.SendChunked = false;
diff --git a/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs b/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs
index 4e8469326..fecd72a39 100644
--- a/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs
+++ b/MediaBrowser.Server.Implementations/ServerManager/ServerManager.cs
@@ -8,7 +8,6 @@ using MediaBrowser.Model.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
-using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
@@ -171,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
throw;
}
- catch (HttpListenerException ex)
+ catch (Exception ex)
{
_logger.ErrorException("Error starting Http Server", ex);
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index fe734bcf8..10dec2da6 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -336,7 +336,7 @@ namespace MediaBrowser.ServerApplication
LibraryMonitor = new LibraryMonitor(LogManager, TaskManager, LibraryManager, ServerConfigurationManager, FileSystemManager);
RegisterSingleInstance(LibraryMonitor);
- ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager, ProviderRepository);
+ ProviderManager = new ProviderManager(HttpClient, ServerConfigurationManager, LibraryMonitor, LogManager, FileSystemManager);
RegisterSingleInstance(ProviderManager);
RegisterSingleInstance<ISearchEngine>(() => new SearchEngine(LogManager, LibraryManager, UserManager));
@@ -548,7 +548,8 @@ namespace MediaBrowser.ServerApplication
GetExports<ILibraryPostScanTask>());
ProviderManager.AddParts(GetExports<IImageProvider>(), GetExports<IMetadataService>(), GetExports<IMetadataProvider>(),
- GetExports<IMetadataSaver>());
+ GetExports<IMetadataSaver>(),
+ GetExports<IImageSaver>());
ImageProcessor.AddParts(GetExports<IImageEnhancer>());