mirror of
https://github.com/jellyfin/jellyfin.git
synced 2024-11-16 10:29:01 -07:00
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
This commit is contained in:
commit
82ca771cb9
@ -293,7 +293,7 @@ namespace MediaBrowser.Api.Images
|
|||||||
|
|
||||||
if (string.IsNullOrEmpty(imagePath))
|
if (string.IsNullOrEmpty(imagePath))
|
||||||
{
|
{
|
||||||
throw new ResourceNotFoundException();
|
throw new ResourceNotFoundException(string.Format("{0} does not have an image of type {1}", item.Name, request.Type));
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if we can avoid a file system lookup by looking for the file in ResolveArgs
|
// See if we can avoid a file system lookup by looking for the file in ResolveArgs
|
||||||
|
@ -566,29 +566,33 @@ namespace MediaBrowser.Controller.Dto
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach People by transforming them into BaseItemPerson (DTO)
|
|
||||||
dto.People = new BaseItemPerson[item.People.Count];
|
|
||||||
|
|
||||||
// Ordering by person type to ensure actors and artists are at the front.
|
// Ordering by person type to ensure actors and artists are at the front.
|
||||||
// This is taking advantage of the fact that they both begin with A
|
// This is taking advantage of the fact that they both begin with A
|
||||||
// This should be improved in the future
|
// This should be improved in the future
|
||||||
var entities = await Task.WhenAll(item.People.OrderBy(i => i.Type).Select(c =>
|
var people = item.People.OrderBy(i => i.Type).ToList();
|
||||||
|
|
||||||
|
// Attach People by transforming them into BaseItemPerson (DTO)
|
||||||
|
dto.People = new BaseItemPerson[people.Count];
|
||||||
|
|
||||||
|
var entities = await Task.WhenAll(people.Select(p => p.Name).Distinct(StringComparer.OrdinalIgnoreCase).Select(c =>
|
||||||
|
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return await _libraryManager.GetPerson(c.Name).ConfigureAwait(false);
|
return await _libraryManager.GetPerson(c).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
_logger.ErrorException("Error getting person {0}", ex, c.Name);
|
_logger.ErrorException("Error getting person {0}", ex, c);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
)).ConfigureAwait(false);
|
)).ConfigureAwait(false);
|
||||||
|
|
||||||
|
var dictionary = entities.ToDictionary(i => i.Name, StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
for (var i = 0; i < item.People.Count; i++)
|
for (var i = 0; i < item.People.Count; i++)
|
||||||
{
|
{
|
||||||
var person = item.People[i];
|
var person = item.People[i];
|
||||||
@ -600,15 +604,15 @@ namespace MediaBrowser.Controller.Dto
|
|||||||
Type = person.Type
|
Type = person.Type
|
||||||
};
|
};
|
||||||
|
|
||||||
var ibnObject = entities[i];
|
Person entity;
|
||||||
|
|
||||||
if (ibnObject != null)
|
if (dictionary.TryGetValue(person.Name, out entity))
|
||||||
{
|
{
|
||||||
var primaryImagePath = ibnObject.PrimaryImagePath;
|
var primaryImagePath = entity.PrimaryImagePath;
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(primaryImagePath))
|
if (!string.IsNullOrEmpty(primaryImagePath))
|
||||||
{
|
{
|
||||||
baseItemPerson.PrimaryImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(ibnObject, ImageType.Primary, primaryImagePath);
|
baseItemPerson.PrimaryImageTag = Kernel.Instance.ImageManager.GetImageCacheTag(entity, ImageType.Primary, primaryImagePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +160,7 @@ namespace MediaBrowser.Controller.Providers
|
|||||||
private void PopulateBaseItemImages(BaseItem item)
|
private void PopulateBaseItemImages(BaseItem item)
|
||||||
{
|
{
|
||||||
var backdropFiles = new List<string>();
|
var backdropFiles = new List<string>();
|
||||||
|
var screenshotFiles = new List<string>();
|
||||||
|
|
||||||
// Primary Image
|
// Primary Image
|
||||||
var image = GetImage(item, "folder");
|
var image = GetImage(item, "folder");
|
||||||
@ -201,6 +202,22 @@ namespace MediaBrowser.Controller.Providers
|
|||||||
item.SetImage(ImageType.Thumb, image.Value.Path);
|
item.SetImage(ImageType.Thumb, image.Value.Path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Thumbnail Image
|
||||||
|
image = GetImage(item, "box");
|
||||||
|
|
||||||
|
if (image.HasValue)
|
||||||
|
{
|
||||||
|
item.SetImage(ImageType.Box, image.Value.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Thumbnail Image
|
||||||
|
image = GetImage(item, "menu");
|
||||||
|
|
||||||
|
if (image.HasValue)
|
||||||
|
{
|
||||||
|
item.SetImage(ImageType.Menu, image.Value.Path);
|
||||||
|
}
|
||||||
|
|
||||||
// Backdrop Image
|
// Backdrop Image
|
||||||
image = GetImage(item, "backdrop");
|
image = GetImage(item, "backdrop");
|
||||||
|
|
||||||
@ -234,7 +251,40 @@ namespace MediaBrowser.Controller.Providers
|
|||||||
{
|
{
|
||||||
item.BackdropImagePaths = backdropFiles;
|
item.BackdropImagePaths = backdropFiles;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
// Screenshot Image
|
||||||
|
image = GetImage(item, "screenshot");
|
||||||
|
|
||||||
|
if (image.HasValue)
|
||||||
|
{
|
||||||
|
screenshotFiles.Add(image.Value.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
unfound = 0;
|
||||||
|
for (var i = 1; i <= 20; i++)
|
||||||
|
{
|
||||||
|
// Screenshot Image
|
||||||
|
image = GetImage(item, "screenshot" + i);
|
||||||
|
|
||||||
|
if (image.HasValue)
|
||||||
|
{
|
||||||
|
screenshotFiles.Add(image.Value.Path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unfound++;
|
||||||
|
|
||||||
|
if (unfound >= 3)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (screenshotFiles.Count > 0)
|
||||||
|
{
|
||||||
|
item.ScreenshotImagePaths = screenshotFiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||||||
public string ResourceName { get; set; }
|
public string ResourceName { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SwaggerService : IRequiresRequestContext, IRestfulService
|
public class SwaggerService : IHasResultFactory, IRestfulService
|
||||||
{
|
{
|
||||||
public IHttpResultFactory HttpResultFactory { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the specified request.
|
/// Gets the specified request.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -35,9 +33,15 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
|||||||
|
|
||||||
var requestedFile = Path.Combine(swaggerDirectory, request.ResourceName.Replace('/', '\\'));
|
var requestedFile = Path.Combine(swaggerDirectory, request.ResourceName.Replace('/', '\\'));
|
||||||
|
|
||||||
return HttpResultFactory.GetStaticFileResult(RequestContext, requestedFile);
|
return ResultFactory.GetStaticFileResult(RequestContext, requestedFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the result factory.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The result factory.</value>
|
||||||
|
public IHttpResultFactory ResultFactory { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the request context.
|
/// Gets or sets the request context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -758,7 +758,19 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||||||
/// <param name="progress">The progress.</param>
|
/// <param name="progress">The progress.</param>
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
public async Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken)
|
public Task ValidateMediaLibrary(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
|
{
|
||||||
|
// Just run the scheduled task so that the user can see it
|
||||||
|
return Task.Run(() => _taskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Validates the media library internal.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="progress">The progress.</param>
|
||||||
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
|
/// <returns>Task.</returns>
|
||||||
|
public async Task ValidateMediaLibraryInternal(IProgress<double> progress, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_logger.Info("Validating media library");
|
_logger.Info("Validating media library");
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="MediaEncoder\fonts\ARIALUNI.TTF" />
|
<EmbeddedResource Include="MediaEncoder\fonts\ARIALUNI.TTF" />
|
||||||
<EmbeddedResource Include="MediaEncoder\fonts\fonts.conf" />
|
<EmbeddedResource Include="MediaEncoder\fonts\fonts.conf" />
|
||||||
<EmbeddedResource Include="MediaEncoder\ffmpeg20130408.zip" />
|
<EmbeddedResource Include="MediaEncoder\ffmpeg20130412.zip" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
<ItemGroup />
|
||||||
|
@ -1 +0,0 @@
|
|||||||
13efb0e506699c6d90c23a7600b3556d91dd31a1
|
|
@ -0,0 +1 @@
|
|||||||
|
1b75cc4abcfd185b6db07bbe433d010f947d50ae
|
@ -237,7 +237,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
|||||||
}
|
}
|
||||||
catch (OperationCanceledException ex)
|
catch (OperationCanceledException ex)
|
||||||
{
|
{
|
||||||
_logger.Debug("{0} cancelled for {1}", provider.GetType().Name, item.Name);
|
_logger.Debug("{0} canceled for {1}", provider.GetType().Name, item.Name);
|
||||||
|
|
||||||
// If the outer cancellation token is the one that caused the cancellation, throw it
|
// If the outer cancellation token is the one that caused the cancellation, throw it
|
||||||
if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken)
|
if (cancellationToken.IsCancellationRequested && ex.CancellationToken == cancellationToken)
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using MediaBrowser.Server.Implementations.Library;
|
||||||
|
|
||||||
namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
||||||
{
|
{
|
||||||
@ -55,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.ScheduledTasks
|
|||||||
|
|
||||||
progress.Report(0);
|
progress.Report(0);
|
||||||
|
|
||||||
return _libraryManager.ValidateMediaLibrary(progress, cancellationToken);
|
return ((LibraryManager)_libraryManager).ValidateMediaLibraryInternal(progress, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -95,6 +95,10 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
return name;
|
return name;
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
function encodeName(name) {
|
||||||
|
return encodeURIComponent(name).replace("'", '%27');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps around jQuery ajax methods to add additional info to the request.
|
* Wraps around jQuery ajax methods to add additional info to the request.
|
||||||
*/
|
*/
|
||||||
@ -867,7 +871,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
throw new Error("null name");
|
throw new Error("null name");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Studios/" + name);
|
var url = self.getUrl("Studios/" + encodeName(name));
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
@ -885,7 +889,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
throw new Error("null name");
|
throw new Error("null name");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Genres/" + name);
|
var url = self.getUrl("Genres/" + encodeName(name));
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
@ -921,7 +925,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
throw new Error("null name");
|
throw new Error("null name");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Persons/" + name);
|
var url = self.getUrl("Persons/" + encodeName(name));
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
@ -1047,7 +1051,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var url = "Persons/" + name + "/Images/" + options.type;
|
var url = "Persons/" + encodeName(name) + "/Images/" + options.type;
|
||||||
|
|
||||||
if (options.index != null) {
|
if (options.index != null) {
|
||||||
url += "/" + options.index;
|
url += "/" + options.index;
|
||||||
@ -1117,7 +1121,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var url = "Genres/" + name + "/Images/" + options.type;
|
var url = "Genres/" + encodeName(name) + "/Images/" + options.type;
|
||||||
|
|
||||||
if (options.index != null) {
|
if (options.index != null) {
|
||||||
url += "/" + options.index;
|
url += "/" + options.index;
|
||||||
@ -1131,7 +1135,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a url for a genre image
|
* Constructs a url for a studio image
|
||||||
* @param {String} name
|
* @param {String} name
|
||||||
* @param {Object} options
|
* @param {Object} options
|
||||||
* Options supports the following properties:
|
* Options supports the following properties:
|
||||||
@ -1152,7 +1156,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var url = "Studios/" + name + "/Images/" + options.type;
|
var url = "Studios/" + encodeName(name) + "/Images/" + options.type;
|
||||||
|
|
||||||
if (options.index != null) {
|
if (options.index != null) {
|
||||||
url += "/" + options.index;
|
url += "/" + options.index;
|
||||||
@ -1739,7 +1743,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
throw new Error("null name");
|
throw new Error("null name");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Users/" + userId + "/ItemsByName/Favorites/" + name);
|
var url = self.getUrl("Users/" + userId + "/ItemsByName/Favorites/" + encodeName(name));
|
||||||
|
|
||||||
var method = isFavorite ? "POST" : "DELETE";
|
var method = isFavorite ? "POST" : "DELETE";
|
||||||
|
|
||||||
@ -1766,7 +1770,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
throw new Error("null name");
|
throw new Error("null name");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Users/" + userId + "/ItemsByName/" + name + "/Rating", {
|
var url = self.getUrl("Users/" + userId + "/ItemsByName/" + encodeName(name) + "/Rating", {
|
||||||
likes: likes
|
likes: likes
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1791,7 +1795,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
throw new Error("null name");
|
throw new Error("null name");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Users/" + userId + "/ItemsByName/" + name + "/Rating");
|
var url = self.getUrl("Users/" + userId + "/ItemsByName/" + encodeName(name) + "/Rating");
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: "DELETE",
|
type: "DELETE",
|
||||||
@ -1815,7 +1819,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout) {
|
|||||||
throw new Error("null name");
|
throw new Error("null name");
|
||||||
}
|
}
|
||||||
|
|
||||||
var url = self.getUrl("Users/" + userId + "/ItemsByName/" + name + "/UserData");
|
var url = self.getUrl("Users/" + userId + "/ItemsByName/" + encodeName(name) + "/UserData");
|
||||||
|
|
||||||
return self.ajax({
|
return self.ajax({
|
||||||
type: "GET",
|
type: "GET",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.76" targetFramework="net45" />
|
<package id="MediaBrowser.ApiClient.Javascript" version="3.0.77" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Common" version="3.9.43" targetFramework="net45" />
|
<package id="ServiceStack.Common" version="3.9.43" targetFramework="net45" />
|
||||||
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
|
<package id="ServiceStack.Text" version="3.9.43" targetFramework="net45" />
|
||||||
</packages>
|
</packages>
|
Loading…
Reference in New Issue
Block a user