mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-07-09 15:20:34 +02:00
Re-worked provider id's, api client, moved people to the api item wrapper and added server error handling
This commit is contained in:
parent
d5cf6d59a3
commit
3f1af19ce7
|
@ -58,6 +58,8 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
wrapper.Children = Kernel.Instance.GetParentalAllowedChildren(folder, userId).Select(c => GetSerializationObject(c, false, userId));
|
wrapper.Children = Kernel.Instance.GetParentalAllowedChildren(folder, userId).Select(c => GetSerializationObject(c, false, userId));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wrapper.People = item.People;
|
||||||
}
|
}
|
||||||
|
|
||||||
return wrapper;
|
return wrapper;
|
||||||
|
@ -136,8 +138,12 @@ namespace MediaBrowser.Api
|
||||||
|
|
||||||
_FFMpegPath = Path.Combine(FFMpegDirectory, filename);
|
_FFMpegPath = Path.Combine(FFMpegDirectory, filename);
|
||||||
|
|
||||||
if (!File.Exists(_FFMpegPath))
|
// Always re-extract the first time to handle new versions
|
||||||
|
if (File.Exists(_FFMpegPath))
|
||||||
{
|
{
|
||||||
|
File.Delete(_FFMpegPath);
|
||||||
|
}
|
||||||
|
|
||||||
// Extract ffprobe
|
// Extract ffprobe
|
||||||
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.Api.FFMpeg." + filename))
|
using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("MediaBrowser.Api.FFMpeg." + filename))
|
||||||
{
|
{
|
||||||
|
@ -147,7 +153,6 @@ namespace MediaBrowser.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return _FFMpegPath;
|
return _FFMpegPath;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,17 +107,18 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ProcessRequest(HttpListenerContext ctx)
|
public override async Task ProcessRequest(HttpListenerContext ctx)
|
||||||
{
|
{
|
||||||
HttpListenerContext = ctx;
|
HttpListenerContext = ctx;
|
||||||
|
|
||||||
if (!RequiresConversion())
|
if (!RequiresConversion())
|
||||||
{
|
{
|
||||||
new StaticFileHandler() { Path = LibraryItem.Path }.ProcessRequest(ctx);
|
await new StaticFileHandler() { Path = LibraryItem.Path }.ProcessRequest(ctx);
|
||||||
return;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await base.ProcessRequest(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ProcessRequest(ctx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract string GetCommandLineArguments();
|
protected abstract string GetCommandLineArguments();
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class GenresHandler : JsonHandler
|
public class GenresHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected sealed override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
@ -17,4 +16,3 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Common.Logging;
|
||||||
|
using MediaBrowser.Common.Net;
|
||||||
using MediaBrowser.Common.Net.Handlers;
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -10,12 +12,12 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class ImageHandler : BaseHandler
|
public class ImageHandler : BaseHandler
|
||||||
{
|
{
|
||||||
private string _ImagePath = string.Empty;
|
private string _ImagePath = null;
|
||||||
private string ImagePath
|
private string ImagePath
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_ImagePath))
|
if (_ImagePath == null)
|
||||||
{
|
{
|
||||||
_ImagePath = GetImagePath();
|
_ImagePath = GetImagePath();
|
||||||
}
|
}
|
||||||
|
@ -24,18 +26,61 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Stream _SourceStream = null;
|
||||||
|
private Stream SourceStream
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
EnsureSourceStream();
|
||||||
|
|
||||||
|
return _SourceStream;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool _SourceStreamEnsured = false;
|
||||||
|
private void EnsureSourceStream()
|
||||||
|
{
|
||||||
|
if (!_SourceStreamEnsured)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_SourceStream = File.OpenRead(ImagePath);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException ex)
|
||||||
|
{
|
||||||
|
StatusCode = 404;
|
||||||
|
Logger.LogException(ex);
|
||||||
|
}
|
||||||
|
catch (DirectoryNotFoundException ex)
|
||||||
|
{
|
||||||
|
StatusCode = 404;
|
||||||
|
Logger.LogException(ex);
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException ex)
|
||||||
|
{
|
||||||
|
StatusCode = 403;
|
||||||
|
Logger.LogException(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_SourceStreamEnsured = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override string ContentType
|
public override string ContentType
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
string extension = Path.GetExtension(ImagePath);
|
EnsureSourceStream();
|
||||||
|
|
||||||
if (extension.EndsWith("png", StringComparison.OrdinalIgnoreCase))
|
if (SourceStream == null)
|
||||||
{
|
{
|
||||||
return "image/png";
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return "image/jpeg";
|
return MimeTypes.GetMimeType(ImagePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,15 +94,15 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
protected override DateTime? GetLastDateModified()
|
protected override DateTime? GetLastDateModified()
|
||||||
{
|
{
|
||||||
try
|
EnsureSourceStream();
|
||||||
|
|
||||||
|
if (SourceStream == null)
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return File.GetLastWriteTime(ImagePath);
|
return File.GetLastWriteTime(ImagePath);
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
return base.GetLastDateModified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int? Height
|
private int? Height
|
||||||
{
|
{
|
||||||
|
@ -142,7 +187,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(imageType))
|
if (string.IsNullOrEmpty(imageType))
|
||||||
{
|
{
|
||||||
return Model.Entities.ImageType.Primary;
|
return ImageType.Primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ImageType)Enum.Parse(typeof(ImageType), imageType, true);
|
return (ImageType)Enum.Parse(typeof(ImageType), imageType, true);
|
||||||
|
@ -153,7 +198,7 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
return Task.Run(() =>
|
||||||
{
|
{
|
||||||
ImageProcessor.ProcessImage(ImagePath, stream, Width, Height, MaxWidth, MaxHeight, Quality);
|
ImageProcessor.ProcessImage(SourceStream, stream, Width, Height, MaxWidth, MaxHeight, Quality);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,23 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class ItemHandler : JsonHandler
|
public class ItemHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected sealed override object ObjectToSerialize
|
protected sealed override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
|
||||||
return ApiService.GetSerializationObject(ItemToSerialize, true, userId);
|
BaseItem item = ItemToSerialize;
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ApiService.GetSerializationObject(item, true, userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual BaseItem ItemToSerialize
|
protected virtual BaseItem ItemToSerialize
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public abstract class ItemListHandler : JsonHandler
|
public abstract class ItemListHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected sealed override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
return ItemsToSerialize.Select(i =>
|
return ItemsToSerialize.Select(i =>
|
||||||
{
|
{
|
||||||
|
@ -17,7 +16,6 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract IEnumerable<BaseItem> ItemsToSerialize
|
protected abstract IEnumerable<BaseItem> ItemsToSerialize
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
using System.IO;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using MediaBrowser.Common.Net.Handlers;
|
|
||||||
using MediaBrowser.Common.Serialization;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
|
||||||
{
|
|
||||||
public abstract class JsonHandler : BaseJsonHandler
|
|
||||||
{
|
|
||||||
protected abstract object ObjectToSerialize { get; }
|
|
||||||
|
|
||||||
protected override Task WriteResponseToOutputStream(Stream stream)
|
|
||||||
{
|
|
||||||
return Task.Run(() =>
|
|
||||||
{
|
|
||||||
JsonSerializer.SerializeToStream(ObjectToSerialize, stream);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +1,13 @@
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class PersonHandler : JsonHandler
|
public class PersonHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected sealed override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
return Kernel.Instance.ItemController.GetPerson(QueryString["name"]);
|
return Kernel.Instance.ItemController.GetPerson(QueryString["name"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class PluginConfigurationHandler : JsonHandler
|
public class PluginConfigurationHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
string pluginName = QueryString["name"];
|
string pluginName = QueryString["name"];
|
||||||
|
|
||||||
|
@ -16,4 +15,3 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Plugins;
|
using MediaBrowser.Model.Plugins;
|
||||||
|
|
||||||
|
@ -7,11 +8,9 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides information about installed plugins
|
/// Provides information about installed plugins
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PluginsHandler : JsonHandler
|
public class PluginsHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
var plugins = Kernel.Instance.Plugins.Select(p =>
|
var plugins = Kernel.Instance.Plugins.Select(p =>
|
||||||
{
|
{
|
||||||
|
@ -34,4 +33,3 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class StudiosHandler : JsonHandler
|
public class StudiosHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
@ -17,4 +16,3 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class UserConfigurationHandler : JsonHandler
|
public class UserConfigurationHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
|
||||||
|
@ -15,4 +14,3 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
|
using MediaBrowser.Controller;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
class UsersHandler : JsonHandler
|
class UsersHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
return Kernel.Instance.Users;
|
return Kernel.Instance.Users;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
|
using MediaBrowser.Common.Net.Handlers;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.Api.HttpHandlers
|
namespace MediaBrowser.Api.HttpHandlers
|
||||||
{
|
{
|
||||||
public class YearsHandler : JsonHandler
|
public class YearsHandler : BaseJsonHandler
|
||||||
{
|
{
|
||||||
protected override object ObjectToSerialize
|
protected override object GetObjectToSerialize()
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
{
|
||||||
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
Folder parent = ApiService.GetItemById(QueryString["id"]) as Folder;
|
||||||
Guid userId = Guid.Parse(QueryString["userid"]);
|
Guid userId = Guid.Parse(QueryString["userid"]);
|
||||||
|
@ -17,4 +16,3 @@ namespace MediaBrowser.Api.HttpHandlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
|
@ -8,9 +8,9 @@ namespace MediaBrowser.Api
|
||||||
{
|
{
|
||||||
public static class ImageProcessor
|
public static class ImageProcessor
|
||||||
{
|
{
|
||||||
public static void ProcessImage(string path, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality)
|
public static void ProcessImage(Stream sourceImageStream, Stream toStream, int? width, int? height, int? maxWidth, int? maxHeight, int? quality)
|
||||||
{
|
{
|
||||||
Image originalImage = Image.FromFile(path);
|
Image originalImage = Image.FromStream(sourceImageStream);
|
||||||
|
|
||||||
var newWidth = originalImage.Width;
|
var newWidth = originalImage.Width;
|
||||||
var newHeight = originalImage.Height;
|
var newHeight = originalImage.Height;
|
||||||
|
|
|
@ -56,7 +56,6 @@
|
||||||
<Compile Include="HttpHandlers\ItemHandler.cs" />
|
<Compile Include="HttpHandlers\ItemHandler.cs" />
|
||||||
<Compile Include="HttpHandlers\ItemListHandler.cs" />
|
<Compile Include="HttpHandlers\ItemListHandler.cs" />
|
||||||
<Compile Include="HttpHandlers\ItemsWithPersonHandler.cs" />
|
<Compile Include="HttpHandlers\ItemsWithPersonHandler.cs" />
|
||||||
<Compile Include="HttpHandlers\JsonHandler.cs" />
|
|
||||||
<Compile Include="HttpHandlers\PersonHandler.cs" />
|
<Compile Include="HttpHandlers\PersonHandler.cs" />
|
||||||
<Compile Include="HttpHandlers\PluginConfigurationHandler.cs" />
|
<Compile Include="HttpHandlers\PluginConfigurationHandler.cs" />
|
||||||
<Compile Include="HttpHandlers\PluginsHandler.cs" />
|
<Compile Include="HttpHandlers\PluginsHandler.cs" />
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MediaBrowser.Model.Configuration;
|
using MediaBrowser.Model.Configuration;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
|
@ -10,20 +9,32 @@ using MediaBrowser.Model.Users;
|
||||||
|
|
||||||
namespace MediaBrowser.ApiInteraction
|
namespace MediaBrowser.ApiInteraction
|
||||||
{
|
{
|
||||||
public class ApiClient : BaseClient
|
public class ApiClient : IDisposable
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the server host name (myserver or 192.168.x.x)
|
||||||
|
/// </summary>
|
||||||
|
public string ServerHostName { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the port number used by the API
|
||||||
|
/// </summary>
|
||||||
|
public int ServerApiPort { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current api url based on hostname and port.
|
||||||
|
/// </summary>
|
||||||
|
protected string ApiUrl
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return string.Format("http://{0}:{1}/mediabrowser/api", ServerHostName, ServerApiPort);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IHttpClient HttpClient { get; set; }
|
||||||
public IJsonSerializer JsonSerializer { get; set; }
|
public IJsonSerializer JsonSerializer { get; set; }
|
||||||
|
|
||||||
public ApiClient()
|
|
||||||
: base()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public ApiClient(HttpClientHandler handler)
|
|
||||||
: base(handler)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets an image url that can be used to download an image from the api
|
/// Gets an image url that can be used to download an image from the api
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -278,5 +289,10 @@ namespace MediaBrowser.ApiInteraction
|
||||||
return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemWrapper<ApiBaseItem>>>(stream);
|
return JsonSerializer.DeserializeFromStream<IEnumerable<ApiBaseItemWrapper<ApiBaseItem>>>(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
HttpClient.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
|
|
||||||
namespace MediaBrowser.ApiInteraction
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Provides a base class used by the api and image services
|
|
||||||
/// </summary>
|
|
||||||
public abstract class BaseClient : IDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the server host name (myserver or 192.168.x.x)
|
|
||||||
/// </summary>
|
|
||||||
public string ServerHostName { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the port number used by the API
|
|
||||||
/// </summary>
|
|
||||||
public int ServerApiPort { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the current api url based on hostname and port.
|
|
||||||
/// </summary>
|
|
||||||
protected string ApiUrl
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return string.Format("http://{0}:{1}/mediabrowser/api", ServerHostName, ServerApiPort);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpClient HttpClient { get; private set; }
|
|
||||||
|
|
||||||
public BaseClient()
|
|
||||||
: this(new HttpClientHandler())
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public BaseClient(HttpClientHandler clientHandler)
|
|
||||||
{
|
|
||||||
clientHandler.AutomaticDecompression = DecompressionMethods.Deflate;
|
|
||||||
|
|
||||||
HttpClient = new HttpClient(clientHandler);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
HttpClient.Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
11
MediaBrowser.ApiInteraction/IHttpClient.cs
Normal file
11
MediaBrowser.ApiInteraction/IHttpClient.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MediaBrowser.ApiInteraction
|
||||||
|
{
|
||||||
|
public interface IHttpClient : IDisposable
|
||||||
|
{
|
||||||
|
Task<Stream> GetStreamAsync(string url);
|
||||||
|
}
|
||||||
|
}
|
|
@ -40,7 +40,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="ApiClient.cs" />
|
<Compile Include="ApiClient.cs" />
|
||||||
<Compile Include="BaseClient.cs" />
|
<Compile Include="IHttpClient.cs" />
|
||||||
<Compile Include="IJsonSerializer.cs" />
|
<Compile Include="IJsonSerializer.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,12 +1,5 @@
|
||||||
using System;
|
using System.Configuration;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.ComponentModel.Composition;
|
|
||||||
using System.ComponentModel.Composition.Hosting;
|
|
||||||
using System.Configuration;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Configuration
|
namespace MediaBrowser.Common.Configuration
|
||||||
|
|
|
@ -185,7 +185,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void ProcessRequest(HttpListenerContext ctx)
|
public virtual async Task ProcessRequest(HttpListenerContext ctx)
|
||||||
{
|
{
|
||||||
HttpListenerContext = ctx;
|
HttpListenerContext = ctx;
|
||||||
|
|
||||||
|
@ -196,6 +196,8 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
|
||||||
ctx.Response.KeepAlive = true;
|
ctx.Response.KeepAlive = true;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
if (SupportsByteRangeRequests && IsRangeRequest)
|
if (SupportsByteRangeRequests && IsRangeRequest)
|
||||||
{
|
{
|
||||||
ctx.Response.Headers["Accept-Ranges"] = "bytes";
|
ctx.Response.Headers["Accept-Ranges"] = "bytes";
|
||||||
|
@ -223,19 +225,32 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StatusCode == 200 || StatusCode == 206)
|
PrepareResponse();
|
||||||
|
|
||||||
|
if (IsResponseValid)
|
||||||
{
|
{
|
||||||
ProcessUncachedResponse(ctx, cacheDuration);
|
await ProcessUncachedRequest(ctx, cacheDuration);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctx.Response.StatusCode = StatusCode;
|
ctx.Response.StatusCode = StatusCode;
|
||||||
ctx.Response.SendChunked = false;
|
ctx.Response.SendChunked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
// It might be too late if some response data has already been transmitted, but try to set this
|
||||||
|
ctx.Response.StatusCode = 500;
|
||||||
|
|
||||||
|
Logger.LogException(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
DisposeResponseStream();
|
DisposeResponseStream();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void ProcessUncachedResponse(HttpListenerContext ctx, TimeSpan cacheDuration)
|
private async Task ProcessUncachedRequest(HttpListenerContext ctx, TimeSpan cacheDuration)
|
||||||
{
|
{
|
||||||
long? totalContentLength = TotalContentLength;
|
long? totalContentLength = TotalContentLength;
|
||||||
|
|
||||||
|
@ -269,7 +284,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
// Set the status code
|
// Set the status code
|
||||||
ctx.Response.StatusCode = StatusCode;
|
ctx.Response.StatusCode = StatusCode;
|
||||||
|
|
||||||
if (StatusCode == 200 || StatusCode == 206)
|
if (IsResponseValid)
|
||||||
{
|
{
|
||||||
// Finally, write the response data
|
// Finally, write the response data
|
||||||
Stream outputStream = ctx.Response.OutputStream;
|
Stream outputStream = ctx.Response.OutputStream;
|
||||||
|
@ -288,23 +303,11 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
outputStream = CompressedStream;
|
outputStream = CompressedStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
await WriteResponseToOutputStream(outputStream);
|
await WriteResponseToOutputStream(outputStream);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logger.LogException(ex);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
DisposeResponseStream();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctx.Response.SendChunked = false;
|
ctx.Response.SendChunked = false;
|
||||||
DisposeResponseStream();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,9 +320,16 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
response.Headers[HttpResponseHeader.LastModified] = lastModified.ToString("r");
|
response.Headers[HttpResponseHeader.LastModified] = lastModified.ToString("r");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gives subclasses a chance to do and prep work, and also to validate data and set an error status code, if needed
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void PrepareResponse()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract Task WriteResponseToOutputStream(Stream stream);
|
protected abstract Task WriteResponseToOutputStream(Stream stream);
|
||||||
|
|
||||||
private void DisposeResponseStream()
|
protected virtual void DisposeResponseStream()
|
||||||
{
|
{
|
||||||
if (CompressedStream != null)
|
if (CompressedStream != null)
|
||||||
{
|
{
|
||||||
|
@ -366,5 +376,13 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsResponseValid
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return StatusCode == 200 || StatusCode == 206;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,58 @@
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Common.Serialization;
|
||||||
|
|
||||||
namespace MediaBrowser.Common.Net.Handlers
|
namespace MediaBrowser.Common.Net.Handlers
|
||||||
{
|
{
|
||||||
public abstract class BaseJsonHandler : BaseHandler
|
public abstract class BaseJsonHandler : BaseHandler
|
||||||
{
|
{
|
||||||
public override string ContentType
|
public override string ContentType
|
||||||
{
|
{
|
||||||
get { return "application/json"; }
|
get { return MimeTypes.JsonMimeType; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool _ObjectToSerializeEnsured = false;
|
||||||
|
private object _ObjectToSerialize;
|
||||||
|
|
||||||
|
private void EnsureObjectToSerialize()
|
||||||
|
{
|
||||||
|
if (!_ObjectToSerializeEnsured)
|
||||||
|
{
|
||||||
|
_ObjectToSerialize = GetObjectToSerialize();
|
||||||
|
|
||||||
|
if (_ObjectToSerialize == null)
|
||||||
|
{
|
||||||
|
StatusCode = 404;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ObjectToSerializeEnsured = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private object ObjectToSerialize
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
EnsureObjectToSerialize();
|
||||||
|
return _ObjectToSerialize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract object GetObjectToSerialize();
|
||||||
|
|
||||||
|
protected override void PrepareResponse()
|
||||||
|
{
|
||||||
|
base.PrepareResponse();
|
||||||
|
|
||||||
|
EnsureObjectToSerialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Task WriteResponseToOutputStream(Stream stream)
|
||||||
|
{
|
||||||
|
return Task.Run(() =>
|
||||||
|
{
|
||||||
|
JsonSerializer.SerializeToStream(ObjectToSerialize, stream);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,37 +28,44 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool FileStreamDiscovered = false;
|
private bool _SourceStreamEnsured = false;
|
||||||
private FileStream _FileStream = null;
|
private Stream _SourceStream = null;
|
||||||
private FileStream FileStream
|
private Stream SourceStream
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (!FileStreamDiscovered)
|
EnsureSourceStream();
|
||||||
{
|
return _SourceStream;
|
||||||
try
|
|
||||||
{
|
|
||||||
_FileStream = File.OpenRead(Path);
|
|
||||||
}
|
|
||||||
catch (FileNotFoundException)
|
|
||||||
{
|
|
||||||
StatusCode = 404;
|
|
||||||
}
|
|
||||||
catch (DirectoryNotFoundException)
|
|
||||||
{
|
|
||||||
StatusCode = 404;
|
|
||||||
}
|
|
||||||
catch (UnauthorizedAccessException)
|
|
||||||
{
|
|
||||||
StatusCode = 403;
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
FileStreamDiscovered = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _FileStream;
|
private void EnsureSourceStream()
|
||||||
|
{
|
||||||
|
if (!_SourceStreamEnsured)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_SourceStream = File.OpenRead(Path);
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException ex)
|
||||||
|
{
|
||||||
|
StatusCode = 404;
|
||||||
|
Logger.LogException(ex);
|
||||||
|
}
|
||||||
|
catch (DirectoryNotFoundException ex)
|
||||||
|
{
|
||||||
|
StatusCode = 404;
|
||||||
|
Logger.LogException(ex);
|
||||||
|
}
|
||||||
|
catch (UnauthorizedAccessException ex)
|
||||||
|
{
|
||||||
|
StatusCode = 403;
|
||||||
|
Logger.LogException(ex);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_SourceStreamEnsured = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,14 +81,14 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
string contentType = ContentType;
|
|
||||||
|
|
||||||
// Can't compress these
|
// Can't compress these
|
||||||
if (IsRangeRequest)
|
if (IsRangeRequest)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string contentType = ContentType;
|
||||||
|
|
||||||
// Don't compress media
|
// Don't compress media
|
||||||
if (contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase))
|
if (contentType.StartsWith("audio/", StringComparison.OrdinalIgnoreCase) || contentType.StartsWith("video/", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
|
@ -95,27 +102,20 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
|
||||||
protected override long? GetTotalContentLength()
|
protected override long? GetTotalContentLength()
|
||||||
{
|
{
|
||||||
try
|
return SourceStream.Length;
|
||||||
{
|
|
||||||
return FileStream.Length;
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return base.GetTotalContentLength();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DateTime? GetLastDateModified()
|
protected override DateTime? GetLastDateModified()
|
||||||
{
|
{
|
||||||
try
|
EnsureSourceStream();
|
||||||
|
|
||||||
|
if (SourceStream == null)
|
||||||
{
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return File.GetLastWriteTime(Path);
|
return File.GetLastWriteTime(Path);
|
||||||
}
|
}
|
||||||
catch
|
|
||||||
{
|
|
||||||
return base.GetLastDateModified();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string ContentType
|
public override string ContentType
|
||||||
{
|
{
|
||||||
|
@ -125,11 +125,14 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PrepareResponse()
|
||||||
|
{
|
||||||
|
base.PrepareResponse();
|
||||||
|
|
||||||
|
EnsureSourceStream();
|
||||||
|
}
|
||||||
|
|
||||||
protected async override Task WriteResponseToOutputStream(Stream stream)
|
protected async override Task WriteResponseToOutputStream(Stream stream)
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (FileStream != null)
|
|
||||||
{
|
{
|
||||||
if (IsRangeRequest)
|
if (IsRangeRequest)
|
||||||
{
|
{
|
||||||
|
@ -153,20 +156,17 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await FileStream.CopyToAsync(stream);
|
await SourceStream.CopyToAsync(stream);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (Exception ex)
|
protected override void DisposeResponseStream()
|
||||||
{
|
{
|
||||||
Logger.LogException("WriteResponseToOutputStream", ex);
|
base.DisposeResponseStream();
|
||||||
}
|
|
||||||
finally
|
if (SourceStream != null)
|
||||||
{
|
{
|
||||||
if (FileStream != null)
|
SourceStream.Dispose();
|
||||||
{
|
|
||||||
FileStream.Dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,10 +188,10 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
|
|
||||||
if (rangeStart > 0)
|
if (rangeStart > 0)
|
||||||
{
|
{
|
||||||
FileStream.Position = rangeStart;
|
SourceStream.Position = rangeStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
await FileStream.CopyToAsync(responseStream);
|
await SourceStream.CopyToAsync(responseStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -200,7 +200,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
private async Task ServePartialRangeRequestWithUnknownTotalContentLength(KeyValuePair<long, long?> requestedRange, Stream responseStream)
|
private async Task ServePartialRangeRequestWithUnknownTotalContentLength(KeyValuePair<long, long?> requestedRange, Stream responseStream)
|
||||||
{
|
{
|
||||||
// Read the entire stream so that we can determine the length
|
// Read the entire stream so that we can determine the length
|
||||||
byte[] bytes = await ReadBytes(FileStream, 0, null);
|
byte[] bytes = await ReadBytes(SourceStream, 0, null);
|
||||||
|
|
||||||
long totalContentLength = bytes.LongLength;
|
long totalContentLength = bytes.LongLength;
|
||||||
|
|
||||||
|
@ -226,7 +226,7 @@ namespace MediaBrowser.Common.Net.Handlers
|
||||||
long rangeLength = 1 + rangeEnd - rangeStart;
|
long rangeLength = 1 + rangeEnd - rangeStart;
|
||||||
|
|
||||||
// Only read the bytes we need
|
// Only read the bytes we need
|
||||||
byte[] bytes = await ReadBytes(FileStream, Convert.ToInt32(rangeStart), Convert.ToInt32(rangeLength));
|
byte[] bytes = await ReadBytes(SourceStream, Convert.ToInt32(rangeStart), Convert.ToInt32(rangeLength));
|
||||||
|
|
||||||
// Content-Length is the length of what we're serving, not the original content
|
// Content-Length is the length of what we're serving, not the original content
|
||||||
HttpListenerContext.Response.ContentLength64 = rangeLength;
|
HttpListenerContext.Response.ContentLength64 = rangeLength;
|
||||||
|
|
|
@ -5,6 +5,8 @@ namespace MediaBrowser.Common.Net
|
||||||
{
|
{
|
||||||
public static class MimeTypes
|
public static class MimeTypes
|
||||||
{
|
{
|
||||||
|
public static string JsonMimeType = "application/json";
|
||||||
|
|
||||||
public static string GetMimeType(string path)
|
public static string GetMimeType(string path)
|
||||||
{
|
{
|
||||||
string ext = Path.GetExtension(path);
|
string ext = Path.GetExtension(path);
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace MediaBrowser.Controller.Xml
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Provides a base class for parsing metadata xml
|
/// Provides a base class for parsing metadata xml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class BaseItemXmlParser<T>
|
public class BaseItemXmlParser<T>
|
||||||
where T : BaseItem, new()
|
where T : BaseItem, new()
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -215,6 +215,32 @@ namespace MediaBrowser.Controller.Xml
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "TMDbId":
|
||||||
|
string tmdb = reader.ReadString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(tmdb))
|
||||||
|
{
|
||||||
|
item.SetProviderId(MetadataProviders.Tmdb, tmdb);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "TVcomId":
|
||||||
|
string TVcomId = reader.ReadString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(TVcomId))
|
||||||
|
{
|
||||||
|
item.SetProviderId(MetadataProviders.Tvcom, TVcomId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "IMDB_ID":
|
||||||
|
case "IMDB":
|
||||||
|
case "IMDbId":
|
||||||
|
string IMDbId = reader.ReadString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(IMDbId))
|
||||||
|
{
|
||||||
|
item.SetProviderId(MetadataProviders.Imdb, IMDbId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case "Genres":
|
case "Genres":
|
||||||
FetchFromGenresNode(reader.ReadSubtree(), item);
|
FetchFromGenresNode(reader.ReadSubtree(), item);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -11,14 +11,9 @@ namespace MediaBrowser.Model.Entities
|
||||||
public class ApiBaseItem : BaseItem
|
public class ApiBaseItem : BaseItem
|
||||||
{
|
{
|
||||||
// TV Series
|
// TV Series
|
||||||
public string TvdbId { get; set; }
|
|
||||||
public string Status { get; set; }
|
public string Status { get; set; }
|
||||||
public IEnumerable<DayOfWeek> AirDays { get; set; }
|
public IEnumerable<DayOfWeek> AirDays { get; set; }
|
||||||
public string AirTime { get; set; }
|
public string AirTime { get; set; }
|
||||||
|
|
||||||
// Movie
|
|
||||||
public string TmdbId { get; set; }
|
|
||||||
public string ImdbId { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -49,6 +44,8 @@ namespace MediaBrowser.Model.Entities
|
||||||
return Type.Equals(type, StringComparison.OrdinalIgnoreCase);
|
return Type.Equals(type, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<PersonInfo> People { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the item does not have a logo, this will hold the Id of the Parent that has one.
|
/// If the item does not have a logo, this will hold the Id of the Parent that has one.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace MediaBrowser.Model.Entities
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public string Tagline { get; set; }
|
public string Tagline { get; set; }
|
||||||
|
|
||||||
|
[IgnoreDataMember]
|
||||||
public IEnumerable<PersonInfo> People { get; set; }
|
public IEnumerable<PersonInfo> People { get; set; }
|
||||||
|
|
||||||
public IEnumerable<string> Studios { get; set; }
|
public IEnumerable<string> Studios { get; set; }
|
||||||
|
@ -56,5 +57,49 @@ namespace MediaBrowser.Model.Entities
|
||||||
public IEnumerable<Video> LocalTrailers { get; set; }
|
public IEnumerable<Video> LocalTrailers { get; set; }
|
||||||
|
|
||||||
public string TrailerUrl { get; set; }
|
public string TrailerUrl { get; set; }
|
||||||
|
|
||||||
|
public Dictionary<string, string> ProviderIds { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a provider id
|
||||||
|
/// </summary>
|
||||||
|
public string GetProviderId(MetadataProviders provider)
|
||||||
|
{
|
||||||
|
return GetProviderId(provider.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a provider id
|
||||||
|
/// </summary>
|
||||||
|
public string GetProviderId(string name)
|
||||||
|
{
|
||||||
|
if (ProviderIds == null)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProviderIds[name];
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a provider id
|
||||||
|
/// </summary>
|
||||||
|
public void SetProviderId(string name, string value)
|
||||||
|
{
|
||||||
|
if (ProviderIds == null)
|
||||||
|
{
|
||||||
|
ProviderIds = new Dictionary<string, string>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ProviderIds[name] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a provider id
|
||||||
|
/// </summary>
|
||||||
|
public void SetProviderId(MetadataProviders provider, string value)
|
||||||
|
{
|
||||||
|
SetProviderId(provider.ToString(), value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
11
MediaBrowser.Model/Entities/MetadataProviders.cs
Normal file
11
MediaBrowser.Model/Entities/MetadataProviders.cs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
namespace MediaBrowser.Model.Entities
|
||||||
|
{
|
||||||
|
public enum MetadataProviders
|
||||||
|
{
|
||||||
|
Imdb,
|
||||||
|
Tmdb,
|
||||||
|
Tvdb,
|
||||||
|
Tvcom
|
||||||
|
}
|
||||||
|
}
|
|
@ -41,6 +41,7 @@
|
||||||
<Compile Include="Entities\Folder.cs" />
|
<Compile Include="Entities\Folder.cs" />
|
||||||
<Compile Include="Entities\Genre.cs" />
|
<Compile Include="Entities\Genre.cs" />
|
||||||
<Compile Include="Entities\ImageType.cs" />
|
<Compile Include="Entities\ImageType.cs" />
|
||||||
|
<Compile Include="Entities\MetadataProviders.cs" />
|
||||||
<Compile Include="Entities\Person.cs" />
|
<Compile Include="Entities\Person.cs" />
|
||||||
<Compile Include="Entities\Studio.cs" />
|
<Compile Include="Entities\Studio.cs" />
|
||||||
<Compile Include="Entities\Video.cs" />
|
<Compile Include="Entities\Video.cs" />
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
<Compile Include="Resolvers\BoxSetResolver.cs" />
|
<Compile Include="Resolvers\BoxSetResolver.cs" />
|
||||||
<Compile Include="Entities\Movie.cs" />
|
<Compile Include="Entities\Movie.cs" />
|
||||||
<Compile Include="Resolvers\MovieResolver.cs" />
|
<Compile Include="Resolvers\MovieResolver.cs" />
|
||||||
<Compile Include="Metadata\MovieXmlParser.cs" />
|
|
||||||
<Compile Include="Plugin.cs" />
|
<Compile Include="Plugin.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
using System.Xml;
|
|
||||||
using MediaBrowser.Controller.Xml;
|
|
||||||
using MediaBrowser.Movies.Entities;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Movies.Metadata
|
|
||||||
{
|
|
||||||
public class MovieXmlParser : BaseItemXmlParser<Movie>
|
|
||||||
{
|
|
||||||
protected override void FetchDataFromXmlNode(XmlReader reader, Movie item)
|
|
||||||
{
|
|
||||||
switch (reader.Name)
|
|
||||||
{
|
|
||||||
case "TMDbId":
|
|
||||||
item.TmdbId = reader.ReadString();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case "IMDB":
|
|
||||||
case "IMDbId":
|
|
||||||
string IMDbId = reader.ReadString();
|
|
||||||
if (!string.IsNullOrWhiteSpace(IMDbId))
|
|
||||||
{
|
|
||||||
item.ImdbId = IMDbId;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
base.FetchDataFromXmlNode(reader, item);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,9 +6,9 @@ using System.Linq;
|
||||||
using MediaBrowser.Controller;
|
using MediaBrowser.Controller;
|
||||||
using MediaBrowser.Controller.Events;
|
using MediaBrowser.Controller.Events;
|
||||||
using MediaBrowser.Controller.Resolvers;
|
using MediaBrowser.Controller.Resolvers;
|
||||||
|
using MediaBrowser.Controller.Xml;
|
||||||
using MediaBrowser.Model.Entities;
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.Movies.Entities;
|
using MediaBrowser.Movies.Entities;
|
||||||
using MediaBrowser.Movies.Metadata;
|
|
||||||
|
|
||||||
namespace MediaBrowser.Movies.Resolvers
|
namespace MediaBrowser.Movies.Resolvers
|
||||||
{
|
{
|
||||||
|
@ -97,7 +97,7 @@ namespace MediaBrowser.Movies.Resolvers
|
||||||
|
|
||||||
if (metadataFile.HasValue)
|
if (metadataFile.HasValue)
|
||||||
{
|
{
|
||||||
new MovieXmlParser().Fetch(item, metadataFile.Value.Key);
|
new BaseItemXmlParser<Movie>().Fetch(item, metadataFile.Value.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
PopulateBonusFeatures(item, args);
|
PopulateBonusFeatures(item, args);
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
using MediaBrowser.Model.Entities;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.TV.Entities
|
namespace MediaBrowser.TV.Entities
|
||||||
{
|
{
|
||||||
public class Series : Folder
|
public class Series : Folder
|
||||||
{
|
{
|
||||||
public string TvdbId { get; set; }
|
|
||||||
public string Status { get; set; }
|
public string Status { get; set; }
|
||||||
public IEnumerable<DayOfWeek> AirDays { get; set; }
|
public IEnumerable<DayOfWeek> AirDays { get; set; }
|
||||||
public string AirTime { get; set; }
|
public string AirTime { get; set; }
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System;
|
using System.IO;
|
||||||
using System.IO;
|
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using MediaBrowser.Controller.Xml;
|
using MediaBrowser.Controller.Xml;
|
||||||
using MediaBrowser.TV.Entities;
|
using MediaBrowser.TV.Entities;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using MediaBrowser.Controller.Xml;
|
using MediaBrowser.Controller.Xml;
|
||||||
|
using MediaBrowser.Model.Entities;
|
||||||
using MediaBrowser.TV.Entities;
|
using MediaBrowser.TV.Entities;
|
||||||
|
|
||||||
namespace MediaBrowser.TV.Metadata
|
namespace MediaBrowser.TV.Metadata
|
||||||
|
@ -12,7 +13,11 @@ namespace MediaBrowser.TV.Metadata
|
||||||
switch (reader.Name)
|
switch (reader.Name)
|
||||||
{
|
{
|
||||||
case "id":
|
case "id":
|
||||||
item.TvdbId = reader.ReadString();
|
string id = reader.ReadString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(id))
|
||||||
|
{
|
||||||
|
item.SetProviderId(MetadataProviders.Tvdb, id);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "Airs_DayOfWeek":
|
case "Airs_DayOfWeek":
|
||||||
|
|
Loading…
Reference in a new issue