mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-05 06:34:13 -04:00
Creating the genre API (using the unimplemented contain api)
This commit is contained in:
parent
7e098b4005
commit
83a463851d
@ -20,13 +20,14 @@ namespace Kyoo.CommonApi
|
|||||||
return operand(left, right);
|
return operand(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Expression<Func<T, bool>> ParseWhere<T>(Dictionary<string, string> where)
|
public static Expression<Func<T, bool>> ParseWhere<T>(Dictionary<string, string> where,
|
||||||
|
Expression<Func<T, bool>> defaultWhere = null)
|
||||||
{
|
{
|
||||||
if (where == null || where.Count == 0)
|
if (where == null || where.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
ParameterExpression param = Expression.Parameter(typeof(T));
|
ParameterExpression param = Expression.Parameter(typeof(T));
|
||||||
Expression expression = null;
|
Expression expression = defaultWhere?.Body;
|
||||||
|
|
||||||
foreach ((string key, string desired) in where)
|
foreach ((string key, string desired) in where)
|
||||||
{
|
{
|
||||||
@ -42,21 +43,26 @@ namespace Kyoo.CommonApi
|
|||||||
if (property == null)
|
if (property == null)
|
||||||
throw new ArgumentException($"No filterable parameter with the name {key}.");
|
throw new ArgumentException($"No filterable parameter with the name {key}.");
|
||||||
MemberExpression propertyExpr = Expression.Property(param, property);
|
MemberExpression propertyExpr = Expression.Property(param, property);
|
||||||
|
|
||||||
Type propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
|
ConstantExpression valueExpr = null;
|
||||||
object val = string.IsNullOrEmpty(value) || value.Equals("null", StringComparison.OrdinalIgnoreCase)
|
if (operand != "ctn")
|
||||||
? null
|
{
|
||||||
: Convert.ChangeType(value, propertyType);
|
Type propertyType = Nullable.GetUnderlyingType(property.PropertyType) ?? property.PropertyType;
|
||||||
ConstantExpression valueExpr = Expression.Constant(val, property.PropertyType);
|
object val = string.IsNullOrEmpty(value) || value.Equals("null", StringComparison.OrdinalIgnoreCase)
|
||||||
|
? null
|
||||||
|
: Convert.ChangeType(value, propertyType);
|
||||||
|
valueExpr = Expression.Constant(val, property.PropertyType);
|
||||||
|
}
|
||||||
|
|
||||||
Expression condition = operand switch
|
Expression condition = operand switch
|
||||||
{
|
{
|
||||||
"eq" => Expression.Equal(propertyExpr, valueExpr),
|
"eq" => Expression.Equal(propertyExpr, valueExpr!),
|
||||||
"not" => Expression.NotEqual(propertyExpr, valueExpr),
|
"not" => Expression.NotEqual(propertyExpr, valueExpr!),
|
||||||
"lt" => StringCompatibleExpression(Expression.LessThan, propertyExpr, valueExpr),
|
"lt" => StringCompatibleExpression(Expression.LessThan, propertyExpr, valueExpr),
|
||||||
"lte" => StringCompatibleExpression(Expression.LessThanOrEqual, propertyExpr, valueExpr),
|
"lte" => StringCompatibleExpression(Expression.LessThanOrEqual, propertyExpr, valueExpr),
|
||||||
"gt" => StringCompatibleExpression(Expression.GreaterThan, propertyExpr, valueExpr),
|
"gt" => StringCompatibleExpression(Expression.GreaterThan, propertyExpr, valueExpr),
|
||||||
"gte" => StringCompatibleExpression(Expression.GreaterThanOrEqual, propertyExpr, valueExpr),
|
"gte" => StringCompatibleExpression(Expression.GreaterThanOrEqual, propertyExpr, valueExpr),
|
||||||
|
"ctn" => ContainsResourceExpression(propertyExpr, value),
|
||||||
_ => throw new ArgumentException($"Invalid operand: {operand}")
|
_ => throw new ArgumentException($"Invalid operand: {operand}")
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -68,5 +74,37 @@ namespace Kyoo.CommonApi
|
|||||||
|
|
||||||
return Expression.Lambda<Func<T, bool>>(expression!, param);
|
return Expression.Lambda<Func<T, bool>>(expression!, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Expression ContainsResourceExpression(MemberExpression xProperty, string value)
|
||||||
|
{
|
||||||
|
// x => x.PROPERTY.Any(y => y.Slug == value)
|
||||||
|
Expression ret = null;
|
||||||
|
ParameterExpression y = Expression.Parameter(xProperty.Type.GenericTypeArguments.First(), "y");
|
||||||
|
foreach (string val in value.Split(','))
|
||||||
|
{
|
||||||
|
MemberExpression yProperty;
|
||||||
|
ConstantExpression yValue;
|
||||||
|
if (int.TryParse(val, out int id))
|
||||||
|
{
|
||||||
|
yProperty = Expression.Property(y, "ID");
|
||||||
|
yValue = Expression.Constant(id);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
yProperty = Expression.Property(y, "Slug");
|
||||||
|
yValue = Expression.Constant(val);
|
||||||
|
}
|
||||||
|
|
||||||
|
LambdaExpression lambda = Expression.Lambda(Expression.Equal(yProperty, yValue), y);
|
||||||
|
Expression iteration = Expression.Call(typeof(Enumerable), "Any", xProperty.Type.GenericTypeArguments,
|
||||||
|
xProperty, lambda);
|
||||||
|
|
||||||
|
if (ret == null)
|
||||||
|
ret = iteration;
|
||||||
|
else
|
||||||
|
ret = Expression.AndAlso(ret, iteration);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,27 +1,92 @@
|
|||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.CommonApi;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Configuration;
|
||||||
|
|
||||||
namespace Kyoo.Api
|
namespace Kyoo.Api
|
||||||
{
|
{
|
||||||
[Route("api/genres")]
|
|
||||||
[Route("api/genre")]
|
[Route("api/genre")]
|
||||||
|
[Route("api/genres")]
|
||||||
[ApiController]
|
[ApiController]
|
||||||
public class GenresAPI : ControllerBase
|
public class GenresAPI : CrudApi<Genre>
|
||||||
{
|
{
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
|
|
||||||
public GenresAPI(ILibraryManager libraryManager)
|
public GenresAPI(ILibraryManager libraryManager, IConfiguration config)
|
||||||
|
: base(libraryManager.GenreRepository, config)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<ActionResult<IEnumerable<Genre>>> Index()
|
[HttpGet("{id:int}/show")]
|
||||||
|
[HttpGet("{id:int}/shows")]
|
||||||
|
[Authorize(Policy = "Read")]
|
||||||
|
public async Task<ActionResult<Page<Show>>> GetShows(int id,
|
||||||
|
[FromQuery] string sortBy,
|
||||||
|
[FromQuery] int afterID,
|
||||||
|
[FromQuery] Dictionary<string, string> where,
|
||||||
|
[FromQuery] int limit = 20)
|
||||||
{
|
{
|
||||||
return (await _libraryManager.GetGenres()).ToList();
|
where.Remove("sortBy");
|
||||||
|
where.Remove("limit");
|
||||||
|
where.Remove("afterID");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ICollection<Show> ressources = await _libraryManager.GetShows(
|
||||||
|
ApiHelper.ParseWhere<Show>(where, x => x.Genres.Any(y => y.ID == id)),
|
||||||
|
new Sort<Show>(sortBy),
|
||||||
|
new Pagination(limit, afterID));
|
||||||
|
|
||||||
|
return Page(ressources, limit);
|
||||||
|
}
|
||||||
|
catch (ItemNotFound)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new {Error = ex.Message});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("{slug}/show")]
|
||||||
|
[HttpGet("{slug}/shows")]
|
||||||
|
[Authorize(Policy = "Read")]
|
||||||
|
public async Task<ActionResult<Page<Show>>> GetShows(string slug,
|
||||||
|
[FromQuery] string sortBy,
|
||||||
|
[FromQuery] int afterID,
|
||||||
|
[FromQuery] Dictionary<string, string> where,
|
||||||
|
[FromQuery] int limit = 20)
|
||||||
|
{
|
||||||
|
where.Remove("sortBy");
|
||||||
|
where.Remove("limit");
|
||||||
|
where.Remove("afterID");
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ICollection<Show> ressources = await _libraryManager.GetShows(
|
||||||
|
ApiHelper.ParseWhere<Show>(where, x => x.Genres.Any(y => y.Slug == slug)),
|
||||||
|
new Sort<Show>(sortBy),
|
||||||
|
new Pagination(limit, afterID));
|
||||||
|
|
||||||
|
return Page(ressources, limit);
|
||||||
|
}
|
||||||
|
catch (ItemNotFound)
|
||||||
|
{
|
||||||
|
return NotFound();
|
||||||
|
}
|
||||||
|
catch (ArgumentException ex)
|
||||||
|
{
|
||||||
|
return BadRequest(new {Error = ex.Message});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user