Updating the search api

This commit is contained in:
Zoe Roux 2020-08-04 20:18:33 +02:00
parent 6a0fb2dd38
commit 2df3562045
18 changed files with 351 additions and 103 deletions

View File

@ -292,6 +292,26 @@ namespace Kyoo.Controllers
Expression<Func<Library, object>> sort,
Pagination limit = default
) => GetLibrariesFromCollection(slug, where, new Sort<Library>(sort), limit);
Task<ICollection<ShowRole>> GetRolesFromPeople(int showID,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default);
Task<ICollection<ShowRole>> GetRolesFromPeople(int showID,
[Optional] Expression<Func<ShowRole, bool>> where,
Expression<Func<ShowRole, object>> sort,
Pagination limit = default
) => GetRolesFromPeople(showID, where, new Sort<ShowRole>(sort), limit);
Task<ICollection<ShowRole>> GetRolesFromPeople(string showSlug,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default);
Task<ICollection<ShowRole>> GetRolesFromPeople(string showSlug,
[Optional] Expression<Func<ShowRole, bool>> where,
Expression<Func<ShowRole, object>> sort,
Pagination limit = default
) => GetRolesFromPeople(showSlug, where, new Sort<ShowRole>(sort), limit);
// Helpers

View File

@ -395,6 +395,26 @@ namespace Kyoo.Controllers
Expression<Func<PeopleLink, object>> sort,
Pagination limit = default
) => GetFromShow(showSlug, where, new Sort<PeopleLink>(sort), limit);
Task<ICollection<ShowRole>> GetFromPeople(int showID,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default);
Task<ICollection<ShowRole>> GetFromPeople(int showID,
[Optional] Expression<Func<ShowRole, bool>> where,
Expression<Func<ShowRole, object>> sort,
Pagination limit = default
) => GetFromPeople(showID, where, new Sort<ShowRole>(sort), limit);
Task<ICollection<ShowRole>> GetFromPeople(string showSlug,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default);
Task<ICollection<ShowRole>> GetFromPeople(string showSlug,
[Optional] Expression<Func<ShowRole, bool>> where,
Expression<Func<ShowRole, object>> sort,
Pagination limit = default
) => GetFromPeople(showSlug, where, new Sort<ShowRole>(sort), limit);
}
public interface IProviderRepository : IRepository<ProviderID> {}
}

View File

@ -411,6 +411,22 @@ namespace Kyoo.Controllers
{
return LibraryRepository.GetFromCollection(slug, where, sort, limit);
}
public Task<ICollection<ShowRole>> GetRolesFromPeople(int id,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default)
{
return PeopleRepository.GetFromPeople(id, where, sort, limit);
}
public Task<ICollection<ShowRole>> GetRolesFromPeople(string slug,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default)
{
return PeopleRepository.GetFromPeople(slug, where, sort, limit);
}
public Task AddShowLink(int showID, int? libraryID, int? collectionID)
{

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Newtonsoft.Json;
namespace Kyoo.Models
@ -21,6 +23,12 @@ namespace Kyoo.Models
set => People.Name = value;
}
public string Poster
{
get => People.Poster;
set => People.Poster = value;
}
public IEnumerable<MetadataID> ExternalIDs
{
get => People.ExternalIDs;
@ -42,11 +50,79 @@ namespace Kyoo.Models
Type = type;
}
public PeopleLink(string slug, string name, string role, string type, string imgPrimary, IEnumerable<MetadataID> externalIDs)
public PeopleLink(string slug,
string name,
string role,
string type,
string poster,
IEnumerable<MetadataID> externalIDs)
{
People = new People(slug, name, imgPrimary, externalIDs);
People = new People(slug, name, poster, externalIDs);
Role = role;
Type = type;
}
}
public class ShowRole : IResource
{
public int ID { get; set; }
public string Role { get; set; }
public string Type { get; set; }
public string Slug { get; set; }
public string Title { get; set; }
public IEnumerable<string> Aliases { get; set; }
[JsonIgnore] public string Path { get; set; }
public string Overview { get; set; }
public Status? Status { get; set; }
public string TrailerUrl { get; set; }
public int? StartYear { get; set; }
public int? EndYear { get; set; }
public string Poster { get; set; }
public string Logo { get; set; }
public string Backdrop { get; set; }
public bool IsMovie { get; set; }
public ShowRole() {}
public ShowRole(PeopleLink x)
{
ID = x.ID;
Role = x.Role;
Type = x.Type;
Slug = x.Show.Slug;
Title = x.Show.Title;
Aliases = x.Show.Aliases;
Path = x.Show.Path;
Overview = x.Show.Overview;
Status = x.Show.Status;
TrailerUrl = x.Show.TrailerUrl;
StartYear = x.Show.StartYear;
EndYear = x.Show.EndYear;
Poster = x.Show.Poster;
Logo = x.Show.Logo;
Backdrop = x.Show.Backdrop;
IsMovie = x.Show.IsMovie;
}
public static Expression<Func<PeopleLink, ShowRole>> FromPeopleRole => x => new ShowRole
{
ID = x.ID,
Role = x.Role,
Type = x.Type,
Slug = x.Show.Slug,
Title = x.Show.Title,
Aliases = x.Show.Aliases,
Path = x.Show.Path,
Overview = x.Show.Overview,
Status = x.Show.Status,
TrailerUrl = x.Show.TrailerUrl,
StartYear = x.Show.StartYear,
EndYear = x.Show.EndYear,
Poster = x.Show.Poster,
Logo = x.Show.Logo,
Backdrop = x.Show.Backdrop,
IsMovie = x.Show.IsMovie
};
}
}

View File

@ -13,7 +13,7 @@ namespace Kyoo.Models
public string Poster { get; set; }
public string Overview { get; set; }
[NotMergable] [JsonIgnore] public virtual IEnumerable<CollectionLink> Links { get; set; }
public virtual IEnumerable<Show> Shows
[JsonIgnore] public virtual IEnumerable<Show> Shows
{
get => Links.Select(x => x.Show);
set => Links = value.Select(x => new CollectionLink(this, x));

View File

@ -9,18 +9,18 @@ namespace Kyoo.Models
public int ID { get; set; }
public string Slug { get; set; }
public string Name { get; set; }
[JsonIgnore] public string ImgPrimary { get; set; }
public string Poster { get; set; }
public virtual IEnumerable<MetadataID> ExternalIDs { get; set; }
[JsonIgnore] public virtual IEnumerable<PeopleLink> Roles { get; set; }
public People() {}
public People(string slug, string name, string imgPrimary, IEnumerable<MetadataID> externalIDs)
public People(string slug, string name, string poster, IEnumerable<MetadataID> externalIDs)
{
Slug = slug;
Name = name;
ImgPrimary = imgPrimary;
Poster = poster;
ExternalIDs = externalIDs;
}
}

View File

@ -77,8 +77,9 @@ namespace Kyoo.Controllers
{
ContractResolver = new JsonPropertySelector(null, new Dictionary<Type, HashSet<string>>()
{
{typeof(Show), new HashSet<string> {"genres", "studio", "people", "seasons"}},
{typeof(Episode), new HashSet<string> {"tracks"}}
{typeof(Show), new HashSet<string> {"genres", "studio"}},
{typeof(Episode), new HashSet<string> {"tracks"}},
{typeof(PeopleLink), new HashSet<string> {"show"}}
})
},
context.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>(),

View File

@ -102,8 +102,8 @@ namespace Kyoo.Controllers
};
}
ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleLinks.Where(x => x.ShowID == showID),
id => _database.PeopleLinks.FirstOrDefaultAsync(x => x.ID == id),
ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleRoles.Where(x => x.ShowID == showID),
id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id),
x => x.People.Name,
where,
sort,
@ -128,8 +128,8 @@ namespace Kyoo.Controllers
};
}
ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleLinks.Where(x => x.Show.Slug == showSlug),
id => _database.PeopleLinks.FirstOrDefaultAsync(x => x.ID == id),
ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleRoles.Where(x => x.Show.Slug == showSlug),
id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id),
x => x.People.Name,
where,
sort,
@ -138,5 +138,39 @@ namespace Kyoo.Controllers
throw new ItemNotFound();
return people;
}
public async Task<ICollection<ShowRole>> GetFromPeople(int peopleID,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default)
{
ICollection<ShowRole> roles = await ApplyFilters(_database.PeopleRoles.Where(x => x.PeopleID == peopleID)
.Select(ShowRole.FromPeopleRole),
async id => new ShowRole(await _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id)),
x => x.Title,
where,
sort,
limit);
if (!roles.Any() && await Get(peopleID) == null)
throw new ItemNotFound();
return roles;
}
public async Task<ICollection<ShowRole>> GetFromPeople(string slug,
Expression<Func<ShowRole, bool>> where = null,
Sort<ShowRole> sort = default,
Pagination limit = default)
{
ICollection<ShowRole> roles = await ApplyFilters(_database.PeopleRoles.Where(x => x.People.Slug == slug)
.Select(ShowRole.FromPeopleRole),
async id => new ShowRole(await _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id)),
x => x.Title,
where,
sort,
limit);
if (!roles.Any() && await Get(slug) == null)
throw new ItemNotFound();
return roles;
}
}
}

View File

@ -78,9 +78,10 @@ namespace Kyoo.Controllers
public override async Task<ICollection<Show>> Search(string query)
{
query = $"%{query}%";
return await _database.Shows
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%")
/*|| EF.Functions.ILike(x.Aliases, $"%{query}%")*/)
.Where(x => EF.Functions.ILike(x.Title, query)
/*|| x.Aliases.Any(y => EF.Functions.ILike(y, query))*/) // NOT TRANSLATABLE.
.Take(20)
.ToListAsync();
}

View File

@ -68,10 +68,10 @@ namespace Kyoo.Controllers
foreach (PeopleLink peop in people)
{
string localPath = Path.Combine(root, peop.People.Slug + ".jpg");
if (peop.People.ImgPrimary == null)
if (peop.People.Poster == null)
continue;
if (alwaysDownload || !File.Exists(localPath))
await DownloadImage(peop.People.ImgPrimary, localPath, $"The profile picture of {peop.People.Name}");
await DownloadImage(peop.People.Poster, localPath, $"The profile picture of {peop.People.Name}");
}
return people;

View File

@ -9,6 +9,7 @@ using IdentityServer4.EntityFramework.Interfaces;
using IdentityServer4.EntityFramework.Options;
using Kyoo.Models;
using Kyoo.Models.Exceptions;
using Kyoo.Models.Watch;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
@ -68,37 +69,46 @@ namespace Kyoo
public DbSet<ProviderID> Providers { get; set; }
public DbSet<MetadataID> MetadataIds { get; set; }
public DbSet<LibraryLink> LibraryLinks { get; set; }
public DbSet<CollectionLink> CollectionLinks { get; set; }
public DbSet<PeopleLink> PeopleLinks { get; set; }
public DbSet<PeopleLink> PeopleRoles { get; set; }
// This is used because EF doesn't support Many-To-Many relationships so for now we need to override the getter/setters to store this.
public DbSet<LibraryLink> LibraryLinks { get; set; }
public DbSet<CollectionLink> CollectionLinks { get; set; }
public DbSet<GenreLink> GenreLinks { get; set; }
public DbSet<ProviderLink> ProviderLinks { get; set; }
private readonly ValueConverter<IEnumerable<string>, string> _stringArrayConverter =
new ValueConverter<IEnumerable<string>, string>(
arr => string.Join("|", arr),
str => str.Split("|", StringSplitOptions.None));
public DatabaseContext()
{
NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
NpgsqlConnection.GlobalTypeMapper.MapEnum<ItemType>();
NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
}
private readonly ValueComparer<IEnumerable<string>> _stringArrayComparer =
new ValueComparer<IEnumerable<string>>(
(l1, l2) => l1.SequenceEqual(l2),
arr => arr.Aggregate(0, (i, s) => s.GetHashCode()));
(l1, l2) => l1.SequenceEqual(l2),
arr => arr.Aggregate(0, (i, s) => s.GetHashCode()));
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Library>().Property(e => e.Paths)
.HasConversion(_stringArrayConverter).Metadata
.SetValueComparer(_stringArrayComparer);
modelBuilder.Entity<Show>().Property(e => e.Aliases)
.HasConversion(_stringArrayConverter).Metadata
.SetValueComparer(_stringArrayComparer);
modelBuilder.HasPostgresEnum<Status>();
modelBuilder.HasPostgresEnum<ItemType>();
modelBuilder.HasPostgresEnum<StreamType>();
modelBuilder.Entity<Library>()
.Property(x => x.Paths)
.HasColumnType("text[]")
.Metadata.SetValueComparer(_stringArrayComparer);
modelBuilder.Entity<Show>()
.Property(x => x.Aliases)
.HasColumnType("text[]")
.Metadata.SetValueComparer(_stringArrayComparer);
modelBuilder.Entity<Track>()
.Property(t => t.IsDefault)
.ValueGeneratedNever();
@ -127,6 +137,7 @@ namespace Kyoo
modelBuilder.Entity<PeopleLink>()
.Ignore(x => x.Slug)
.Ignore(x => x.Name)
.Ignore(x => x.Poster)
.Ignore(x => x.ExternalIDs);
modelBuilder.Entity<Genre>()

View File

@ -1,5 +1,6 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using Kyoo;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -10,13 +11,16 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace Kyoo.Models.DatabaseMigrations.Internal
{
[DbContext(typeof(DatabaseContext))]
[Migration("20200803040029_Initial")]
[Migration("20200804172021_Initial")]
partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:Enum:item_type", "show,movie,collection")
.HasAnnotation("Npgsql:Enum:status", "finished,airing,planned,unknown")
.HasAnnotation("Npgsql:Enum:stream_type", "unknow,video,audio,subtitle")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.3")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
@ -167,8 +171,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Paths")
.HasColumnType("text");
b.Property<IEnumerable<string>>("Paths")
.HasColumnType("text[]");
b.Property<string>("Slug")
.HasColumnType("text");
@ -262,10 +266,10 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("ImgPrimary")
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Name")
b.Property<string>("Poster")
.HasColumnType("text");
b.Property<string>("Slug")
@ -304,7 +308,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("ShowID");
b.ToTable("PeopleLinks");
b.ToTable("PeopleRoles");
});
modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
@ -393,8 +397,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Aliases")
.HasColumnType("text");
b.Property<IEnumerable<string>>("Aliases")
.HasColumnType("text[]");
b.Property<string>("Backdrop")
.HasColumnType("text");

View File

@ -8,6 +8,11 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterDatabase()
.Annotation("Npgsql:Enum:item_type", "show,movie,collection")
.Annotation("Npgsql:Enum:status", "finished,airing,planned,unknown")
.Annotation("Npgsql:Enum:stream_type", "unknow,video,audio,subtitle");
migrationBuilder.CreateTable(
name: "Collections",
columns: table => new
@ -46,7 +51,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Slug = table.Column<string>(nullable: true),
Name = table.Column<string>(nullable: true),
Paths = table.Column<string>(nullable: true)
Paths = table.Column<string[]>(type: "text[]", nullable: true)
},
constraints: table =>
{
@ -61,7 +66,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Slug = table.Column<string>(nullable: true),
Name = table.Column<string>(nullable: true),
ImgPrimary = table.Column<string>(nullable: true)
Poster = table.Column<string>(nullable: true)
},
constraints: table =>
{
@ -131,7 +136,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Slug = table.Column<string>(nullable: true),
Title = table.Column<string>(nullable: true),
Aliases = table.Column<string>(nullable: true),
Aliases = table.Column<string[]>(type: "text[]", nullable: true),
Path = table.Column<string>(nullable: true),
Overview = table.Column<string>(nullable: true),
Status = table.Column<int>(nullable: true),
@ -239,7 +244,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
});
migrationBuilder.CreateTable(
name: "PeopleLinks",
name: "PeopleRoles",
columns: table => new
{
ID = table.Column<int>(nullable: false)
@ -251,15 +256,15 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
},
constraints: table =>
{
table.PrimaryKey("PK_PeopleLinks", x => x.ID);
table.PrimaryKey("PK_PeopleRoles", x => x.ID);
table.ForeignKey(
name: "FK_PeopleLinks_People_PeopleID",
name: "FK_PeopleRoles_People_PeopleID",
column: x => x.PeopleID,
principalTable: "People",
principalColumn: "ID",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_PeopleLinks_Shows_ShowID",
name: "FK_PeopleRoles_Shows_ShowID",
column: x => x.ShowID,
principalTable: "Shows",
principalColumn: "ID",
@ -500,13 +505,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
unique: true);
migrationBuilder.CreateIndex(
name: "IX_PeopleLinks_PeopleID",
table: "PeopleLinks",
name: "IX_PeopleRoles_PeopleID",
table: "PeopleRoles",
column: "PeopleID");
migrationBuilder.CreateIndex(
name: "IX_PeopleLinks_ShowID",
table: "PeopleLinks",
name: "IX_PeopleRoles_ShowID",
table: "PeopleRoles",
column: "ShowID");
migrationBuilder.CreateIndex(
@ -569,7 +574,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
name: "MetadataIds");
migrationBuilder.DropTable(
name: "PeopleLinks");
name: "PeopleRoles");
migrationBuilder.DropTable(
name: "ProviderLinks");

View File

@ -1,5 +1,6 @@
// <auto-generated />
using System;
using System.Collections.Generic;
using Kyoo;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
@ -15,6 +16,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("Npgsql:Enum:item_type", "show,movie,collection")
.HasAnnotation("Npgsql:Enum:status", "finished,airing,planned,unknown")
.HasAnnotation("Npgsql:Enum:stream_type", "unknow,video,audio,subtitle")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
.HasAnnotation("ProductVersion", "3.1.3")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
@ -165,8 +169,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Paths")
.HasColumnType("text");
b.Property<IEnumerable<string>>("Paths")
.HasColumnType("text[]");
b.Property<string>("Slug")
.HasColumnType("text");
@ -260,10 +264,10 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("ImgPrimary")
b.Property<string>("Name")
.HasColumnType("text");
b.Property<string>("Name")
b.Property<string>("Poster")
.HasColumnType("text");
b.Property<string>("Slug")
@ -302,7 +306,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("ShowID");
b.ToTable("PeopleLinks");
b.ToTable("PeopleRoles");
});
modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
@ -391,8 +395,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("integer")
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
b.Property<string>("Aliases")
.HasColumnType("text");
b.Property<IEnumerable<string>>("Aliases")
.HasColumnType("text[]");
b.Property<string>("Backdrop")
.HasColumnType("text");

View File

@ -1,36 +0,0 @@
using System.Linq;
using System.Threading.Tasks;
using Kyoo.Controllers;
using Kyoo.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace Kyoo.Api
{
[Route("api/[controller]")]
[ApiController]
public class PeopleController : ControllerBase
{
private readonly ILibraryManager _libraryManager;
public PeopleController(ILibraryManager libraryManager)
{
_libraryManager = libraryManager;
}
[HttpGet("{peopleSlug}")]
[Authorize(Policy="Read")]
public async Task<ActionResult<Collection>> GetPeople(string peopleSlug)
{
People people = await _libraryManager.GetPeople(peopleSlug);
if (people == null)
return NotFound();
return new Collection(people.Slug, people.Name, null, null)
{
Shows = people.Roles.Select(x => x.Show),
Poster = "peopleimg/" + people.Slug
};
}
}
}

View File

@ -0,0 +1,93 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Kyoo.CommonApi;
using Kyoo.Controllers;
using Kyoo.Models;
using Kyoo.Models.Exceptions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
namespace Kyoo.Api
{
[Route("api/people")]
[ApiController]
public class PeopleApi : CrudApi<People>
{
private readonly ILibraryManager _libraryManager;
public PeopleApi(ILibraryManager libraryManager, IConfiguration configuration)
: base(libraryManager.PeopleRepository, configuration)
{
_libraryManager = libraryManager;
}
[HttpGet("{id:int}/role")]
[HttpGet("{id:int}/roles")]
[Authorize(Policy = "Read")]
[JsonDetailed]
public async Task<ActionResult<Page<ShowRole>>> GetRoles(int id,
[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<ShowRole> resources = await _libraryManager.GetRolesFromPeople(id,
ApiHelper.ParseWhere<ShowRole>(where),
new Sort<ShowRole>(sortBy),
new Pagination(limit, afterID));
return Page(resources, limit);
}
catch (ItemNotFound)
{
return NotFound();
}
catch (ArgumentException ex)
{
return BadRequest(new {Error = ex.Message});
}
}
[HttpGet("{slug}/role")]
[HttpGet("{slug}/roles")]
[Authorize(Policy = "Read")]
[JsonDetailed]
public async Task<ActionResult<Page<ShowRole>>> GetRoles(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<ShowRole> ressources = await _libraryManager.GetRolesFromPeople(slug,
ApiHelper.ParseWhere<ShowRole>(where),
new Sort<ShowRole>(sortBy),
new Pagination(limit, afterID));
return Page(ressources, limit);
}
catch (ItemNotFound)
{
return NotFound();
}
catch (ArgumentException ex)
{
return BadRequest(new {Error = ex.Message});
}
}
}
}

View File

@ -6,13 +6,13 @@ using Microsoft.AspNetCore.Mvc;
namespace Kyoo.Api
{
[Route("api/[controller]")]
[Route("api/search")]
[ApiController]
public class SearchController : ControllerBase
public class SearchApi : ControllerBase
{
private readonly ILibraryManager _libraryManager;
public SearchController(ILibraryManager libraryManager)
public SearchApi(ILibraryManager libraryManager)
{
_libraryManager = libraryManager;
}
@ -21,7 +21,7 @@ namespace Kyoo.Api
[Authorize(Policy="Read")]
public async Task<ActionResult<SearchResult>> Search(string query)
{
SearchResult result = new SearchResult
return new SearchResult
{
Query = query,
Collections = await _libraryManager.SearchCollections(query),
@ -31,7 +31,6 @@ namespace Kyoo.Api
Genres = await _libraryManager.SearchGenres(query),
Studios = await _libraryManager.SearchStudios(query)
};
return result;
}
}
}

@ -1 +1 @@
Subproject commit de1b3b069aa4f920bd5248223eda151b1eedf541
Subproject commit 3dad4b29d6565d08ef0bce1e450b5de65f6fac16