mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
API: documenting watch items
This commit is contained in:
parent
7e4fab1ee1
commit
049f545d51
@ -200,10 +200,11 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// Get the resource by a filter function or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="where">The filter function.</param>
|
||||
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
||||
/// <typeparam name="T">The type of the resource</typeparam>
|
||||
/// <returns>The first resource found that match the where function</returns>
|
||||
[ItemCanBeNull]
|
||||
Task<T> GetOrDefault<T>(Expression<Func<T, bool>> where)
|
||||
Task<T> GetOrDefault<T>(Expression<Func<T, bool>> where, Sort<T> sortBy = default)
|
||||
where T : class, IResource;
|
||||
|
||||
/// <summary>
|
||||
|
@ -81,9 +81,10 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// Get the first resource that match the predicate or null if it is not found.
|
||||
/// </summary>
|
||||
/// <param name="where">A predicate to filter the resource.</param>
|
||||
/// <param name="sortBy">A custom sort method to handle cases where multiples items match the filters.</param>
|
||||
/// <returns>The resource found</returns>
|
||||
[ItemCanBeNull]
|
||||
Task<T> GetOrDefault(Expression<Func<T, bool>> where);
|
||||
Task<T> GetOrDefault(Expression<Func<T, bool>> where, Sort<T> sortBy = default);
|
||||
|
||||
/// <summary>
|
||||
/// Search for resources.
|
||||
@ -263,6 +264,8 @@ namespace Kyoo.Abstractions.Controllers
|
||||
/// </summary>
|
||||
public interface IEpisodeRepository : IRepository<Episode>
|
||||
{
|
||||
// TODO replace the next methods with extension methods.
|
||||
|
||||
/// <summary>
|
||||
/// Get a episode from it's showID, it's seasonNumber and it's episode number.
|
||||
/// </summary>
|
||||
|
@ -158,36 +158,50 @@ namespace Kyoo.Abstractions.Models
|
||||
/// <returns>A new WatchItem representing the given episode.</returns>
|
||||
public static async Task<WatchItem> FromEpisode(Episode ep, ILibraryManager library)
|
||||
{
|
||||
Episode previous = null;
|
||||
Episode next = null;
|
||||
|
||||
await library.Load(ep, x => x.Show);
|
||||
await library.Load(ep, x => x.Tracks);
|
||||
|
||||
if (!ep.Show.IsMovie && ep.SeasonNumber != null && ep.EpisodeNumber != null)
|
||||
Episode previous = null;
|
||||
Episode next = null;
|
||||
if (!ep.Show.IsMovie)
|
||||
{
|
||||
if (ep.EpisodeNumber > 1)
|
||||
previous = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber.Value, ep.EpisodeNumber.Value - 1);
|
||||
else if (ep.SeasonNumber > 1)
|
||||
if (ep.AbsoluteNumber != null)
|
||||
{
|
||||
previous = (await library.GetAll(x => x.ShowID == ep.ShowID
|
||||
&& x.SeasonNumber == ep.SeasonNumber.Value - 1,
|
||||
limit: 1,
|
||||
sort: new Sort<Episode>(x => x.EpisodeNumber, true))
|
||||
).FirstOrDefault();
|
||||
previous = await library.GetOrDefault(
|
||||
x => x.ShowID == ep.ShowID && x.AbsoluteNumber <= ep.AbsoluteNumber,
|
||||
new Sort<Episode>(x => x.AbsoluteNumber, true)
|
||||
);
|
||||
next = await library.GetOrDefault(
|
||||
x => x.ShowID == ep.ShowID && x.AbsoluteNumber >= ep.AbsoluteNumber,
|
||||
new Sort<Episode>(x => x.AbsoluteNumber)
|
||||
);
|
||||
}
|
||||
else if (ep.SeasonNumber != null && ep.EpisodeNumber != null)
|
||||
{
|
||||
previous = await library.GetOrDefault(
|
||||
x => x.ShowID == ep.ShowID
|
||||
&& x.SeasonNumber == ep.SeasonNumber
|
||||
&& x.EpisodeNumber < ep.EpisodeNumber,
|
||||
new Sort<Episode>(x => x.EpisodeNumber, true)
|
||||
);
|
||||
previous ??= await library.GetOrDefault(
|
||||
x => x.ShowID == ep.ShowID
|
||||
&& x.SeasonNumber == ep.SeasonNumber - 1,
|
||||
new Sort<Episode>(x => x.EpisodeNumber, true)
|
||||
);
|
||||
|
||||
if (ep.EpisodeNumber >= await library.GetCount<Episode>(x => x.SeasonID == ep.SeasonID))
|
||||
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber.Value + 1, 1);
|
||||
else
|
||||
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber.Value, ep.EpisodeNumber.Value + 1);
|
||||
}
|
||||
else if (!ep.Show.IsMovie && ep.AbsoluteNumber != null)
|
||||
{
|
||||
previous = await library.GetOrDefault<Episode>(x => x.ShowID == ep.ShowID
|
||||
&& x.AbsoluteNumber == ep.EpisodeNumber + 1);
|
||||
next = await library.GetOrDefault<Episode>(x => x.ShowID == ep.ShowID
|
||||
&& x.AbsoluteNumber == ep.AbsoluteNumber + 1);
|
||||
next = await library.GetOrDefault(
|
||||
x => x.ShowID == ep.ShowID
|
||||
&& x.SeasonNumber == ep.SeasonNumber
|
||||
&& x.EpisodeNumber > ep.EpisodeNumber,
|
||||
new Sort<Episode>(x => x.EpisodeNumber)
|
||||
);
|
||||
next ??= await library.GetOrDefault(
|
||||
x => x.ShowID == ep.ShowID
|
||||
&& x.SeasonNumber == ep.SeasonNumber + 1,
|
||||
new Sort<Episode>(x => x.EpisodeNumber)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return new WatchItem
|
||||
|
@ -163,10 +163,10 @@ namespace Kyoo.Core.Controllers
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public async Task<T> GetOrDefault<T>(Expression<Func<T, bool>> where)
|
||||
public async Task<T> GetOrDefault<T>(Expression<Func<T, bool>> where, Sort<T> sortBy)
|
||||
where T : class, IResource
|
||||
{
|
||||
return await GetRepository<T>().GetOrDefault(where);
|
||||
return await GetRepository<T>().GetOrDefault(where, sortBy);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -115,9 +115,12 @@ namespace Kyoo.Core.Controllers
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual Task<T> GetOrDefault(Expression<Func<T, bool>> where)
|
||||
public virtual Task<T> GetOrDefault(Expression<Func<T, bool>> where, Sort<T> sortBy = default)
|
||||
{
|
||||
return Database.Set<T>().FirstOrDefaultAsync(where);
|
||||
IQueryable<T> query = Database.Set<T>();
|
||||
Expression<Func<T, object>> sortKey = sortBy.Key ?? DefaultSort;
|
||||
query = sortBy.Descendant ? query.OrderByDescending(sortKey) : query.OrderBy(sortKey);
|
||||
return query.FirstOrDefaultAsync(where);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
|
@ -23,10 +23,6 @@ using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Core.Models.Options;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Kyoo.Core.Api
|
||||
{
|
||||
|
@ -29,8 +29,8 @@ namespace Kyoo.Core.Api
|
||||
{
|
||||
public class JsonPropertyIgnorer : CamelCasePropertyNamesContractResolver
|
||||
{
|
||||
private int _depth = -1;
|
||||
private readonly Uri _host;
|
||||
private int _depth = -1;
|
||||
|
||||
public JsonPropertyIgnorer(Uri host)
|
||||
{
|
||||
|
83
src/Kyoo.Core/Views/Watch/WatchApi.cs
Normal file
83
src/Kyoo.Core/Views/Watch/WatchApi.cs
Normal file
@ -0,0 +1,83 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Attributes;
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Kyoo.Abstractions.Models.Utils;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using static Kyoo.Abstractions.Models.Utils.Constants;
|
||||
|
||||
namespace Kyoo.Core.Api
|
||||
{
|
||||
/// <summary>
|
||||
/// Retrieve information of an <see cref="Episode"/> as a <see cref="WatchItem"/>.
|
||||
/// A watch item is another representation of an episode in a form easier to read and display for playback.
|
||||
/// It contains streams (video, audio, subtitles) information, chapters, next and previous episodes and a bit of
|
||||
/// information of the show.
|
||||
/// </summary>
|
||||
[Route("api/watch")]
|
||||
[Route("api/watchitem", Order = AlternativeRoute)]
|
||||
[ApiController]
|
||||
[ApiDefinition("Watch Items", Group = WatchGroup)]
|
||||
public class WatchApi : ControllerBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The library manager used to modify or retrieve information in the data store.
|
||||
/// </summary>
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="WatchApi"/>.
|
||||
/// </summary>
|
||||
/// <param name="libraryManager">
|
||||
/// The library manager used to modify or retrieve information in the data store.
|
||||
/// </param>
|
||||
public WatchApi(ILibraryManager libraryManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a watch item
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Retrieve a watch item of an episode.
|
||||
/// </remarks>
|
||||
/// <param name="identifier">The ID or slug of the <see cref="Episode"/>.</param>
|
||||
/// <returns>A page of items.</returns>
|
||||
/// <response code="404">No episode with the given ID or slug could be found.</response>
|
||||
[HttpGet("{identifier:id}")]
|
||||
[Permission("watch", Kind.Read)]
|
||||
[ProducesResponseType(StatusCodes.Status200OK)]
|
||||
[ProducesResponseType(StatusCodes.Status404NotFound)]
|
||||
public async Task<ActionResult<WatchItem>> GetWatchItem(Identifier identifier)
|
||||
{
|
||||
Episode item = await identifier.Match(
|
||||
id => _libraryManager.GetOrDefault<Episode>(id),
|
||||
slug => _libraryManager.GetOrDefault<Episode>(slug)
|
||||
);
|
||||
if (item == null)
|
||||
return NotFound();
|
||||
return await WatchItem.FromEpisode(item, _libraryManager);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
// Kyoo - A portable and vast media library solution.
|
||||
// Copyright (c) Kyoo.
|
||||
//
|
||||
// See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
//
|
||||
// Kyoo is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// any later version.
|
||||
//
|
||||
// Kyoo is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Abstractions.Models.Exceptions;
|
||||
using Kyoo.Abstractions.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Kyoo.Core.Api
|
||||
{
|
||||
[Route("api/watch")]
|
||||
[ApiController]
|
||||
public class WatchApi : ControllerBase
|
||||
{
|
||||
private readonly ILibraryManager _libraryManager;
|
||||
|
||||
public WatchApi(ILibraryManager libraryManager)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
[HttpGet("{slug}")]
|
||||
[Permission("video", Kind.Read)]
|
||||
public async Task<ActionResult<WatchItem>> GetWatchItem(string slug)
|
||||
{
|
||||
try
|
||||
{
|
||||
Episode item = await _libraryManager.Get<Episode>(slug);
|
||||
return await WatchItem.FromEpisode(item, _libraryManager);
|
||||
}
|
||||
catch (ItemNotFoundException)
|
||||
{
|
||||
return NotFound();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user