mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-04 03:27:14 -05:00 
			
		
		
		
	Updating the search api
This commit is contained in:
		
							parent
							
								
									6a0fb2dd38
								
							
						
					
					
						commit
						2df3562045
					
				@ -293,6 +293,26 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
			Pagination limit = default
 | 
								Pagination limit = default
 | 
				
			||||||
		) => GetLibrariesFromCollection(slug, where, new Sort<Library>(sort), limit);
 | 
							) => 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
 | 
							// Helpers
 | 
				
			||||||
		Task AddShowLink(int showID, int? libraryID, int? collectionID);
 | 
							Task AddShowLink(int showID, int? libraryID, int? collectionID);
 | 
				
			||||||
 | 
				
			|||||||
@ -395,6 +395,26 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
			Expression<Func<PeopleLink, object>> sort,
 | 
								Expression<Func<PeopleLink, object>> sort,
 | 
				
			||||||
			Pagination limit = default
 | 
								Pagination limit = default
 | 
				
			||||||
		) => GetFromShow(showSlug, where, new Sort<PeopleLink>(sort), limit);
 | 
							) => 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> {}
 | 
						public interface IProviderRepository : IRepository<ProviderID> {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -412,6 +412,22 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
			return LibraryRepository.GetFromCollection(slug, where, sort, limit);
 | 
								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)
 | 
							public Task AddShowLink(int showID, int? libraryID, int? collectionID)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return ShowRepository.AddShowLink(showID, libraryID, collectionID);
 | 
								return ShowRepository.AddShowLink(showID, libraryID, collectionID);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,6 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
using Newtonsoft.Json;
 | 
					using Newtonsoft.Json;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Models
 | 
					namespace Kyoo.Models
 | 
				
			||||||
@ -21,6 +23,12 @@ namespace Kyoo.Models
 | 
				
			|||||||
			set => People.Name = value;
 | 
								set => People.Name = value;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 | 
							public string Poster
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								get => People.Poster;
 | 
				
			||||||
 | 
								set => People.Poster = value;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		public IEnumerable<MetadataID> ExternalIDs
 | 
							public IEnumerable<MetadataID> ExternalIDs
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			get => People.ExternalIDs;
 | 
								get => People.ExternalIDs;
 | 
				
			||||||
@ -42,11 +50,79 @@ namespace Kyoo.Models
 | 
				
			|||||||
			Type = type;
 | 
								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;
 | 
								Role = role;
 | 
				
			||||||
			Type = type;
 | 
								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
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -13,7 +13,7 @@ namespace Kyoo.Models
 | 
				
			|||||||
		public string Poster { get; set; }
 | 
							public string Poster { get; set; }
 | 
				
			||||||
		public string Overview { get; set; }
 | 
							public string Overview { get; set; }
 | 
				
			||||||
		[NotMergable] [JsonIgnore] public virtual IEnumerable<CollectionLink> Links { 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);
 | 
								get => Links.Select(x => x.Show);
 | 
				
			||||||
			set => Links = value.Select(x => new CollectionLink(this, x));
 | 
								set => Links = value.Select(x => new CollectionLink(this, x));
 | 
				
			||||||
 | 
				
			|||||||
@ -9,18 +9,18 @@ namespace Kyoo.Models
 | 
				
			|||||||
		public int ID { get; set; }
 | 
							public int ID { get; set; }
 | 
				
			||||||
		public string Slug { get; set; }
 | 
							public string Slug { get; set; }
 | 
				
			||||||
		public string Name { 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; }
 | 
							public virtual IEnumerable<MetadataID> ExternalIDs { get; set; }
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		[JsonIgnore] public virtual IEnumerable<PeopleLink> Roles { get; set; }
 | 
							[JsonIgnore] public virtual IEnumerable<PeopleLink> Roles { get; set; }
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		public People() {}
 | 
							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;
 | 
								Slug = slug;
 | 
				
			||||||
			Name = name;
 | 
								Name = name;
 | 
				
			||||||
			ImgPrimary = imgPrimary;
 | 
								Poster = poster;
 | 
				
			||||||
			ExternalIDs = externalIDs;
 | 
								ExternalIDs = externalIDs;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -77,8 +77,9 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
					{
 | 
										{
 | 
				
			||||||
						ContractResolver = new JsonPropertySelector(null, new Dictionary<Type, HashSet<string>>()
 | 
											ContractResolver = new JsonPropertySelector(null, new Dictionary<Type, HashSet<string>>()
 | 
				
			||||||
						{
 | 
											{
 | 
				
			||||||
							{typeof(Show), new HashSet<string> {"genres", "studio", "people", "seasons"}},
 | 
												{typeof(Show), new HashSet<string> {"genres", "studio"}},
 | 
				
			||||||
							{typeof(Episode), new HashSet<string> {"tracks"}}
 | 
												{typeof(Episode), new HashSet<string> {"tracks"}},
 | 
				
			||||||
 | 
												{typeof(PeopleLink), new HashSet<string> {"show"}}
 | 
				
			||||||
						})
 | 
											})
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
				context.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>(), 
 | 
									context.HttpContext.RequestServices.GetRequiredService<ArrayPool<char>>(), 
 | 
				
			||||||
 | 
				
			|||||||
@ -102,8 +102,8 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
				};
 | 
									};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleLinks.Where(x => x.ShowID == showID),
 | 
								ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleRoles.Where(x => x.ShowID == showID),
 | 
				
			||||||
				id => _database.PeopleLinks.FirstOrDefaultAsync(x => x.ID == id),
 | 
									id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id),
 | 
				
			||||||
				x => x.People.Name,
 | 
									x => x.People.Name,
 | 
				
			||||||
				where,
 | 
									where,
 | 
				
			||||||
				sort,
 | 
									sort,
 | 
				
			||||||
@ -128,8 +128,8 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
				};
 | 
									};
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleLinks.Where(x => x.Show.Slug == showSlug),
 | 
								ICollection<PeopleLink> people = await ApplyFilters(_database.PeopleRoles.Where(x => x.Show.Slug == showSlug),
 | 
				
			||||||
				id => _database.PeopleLinks.FirstOrDefaultAsync(x => x.ID == id),
 | 
									id => _database.PeopleRoles.FirstOrDefaultAsync(x => x.ID == id),
 | 
				
			||||||
				x => x.People.Name,
 | 
									x => x.People.Name,
 | 
				
			||||||
				where,
 | 
									where,
 | 
				
			||||||
				sort,
 | 
									sort,
 | 
				
			||||||
@ -138,5 +138,39 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
				throw new ItemNotFound();
 | 
									throw new ItemNotFound();
 | 
				
			||||||
			return people;
 | 
								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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -78,9 +78,10 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		public override async Task<ICollection<Show>> Search(string query)
 | 
							public override async Task<ICollection<Show>> Search(string query)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								query = $"%{query}%";
 | 
				
			||||||
			return await _database.Shows
 | 
								return await _database.Shows
 | 
				
			||||||
				.Where(x => EF.Functions.ILike(x.Title, $"%{query}%") 
 | 
									.Where(x => EF.Functions.ILike(x.Title, query) 
 | 
				
			||||||
				            /*|| EF.Functions.ILike(x.Aliases, $"%{query}%")*/)
 | 
									            /*|| x.Aliases.Any(y => EF.Functions.ILike(y, query))*/) // NOT TRANSLATABLE.
 | 
				
			||||||
				.Take(20)
 | 
									.Take(20)
 | 
				
			||||||
				.ToListAsync();
 | 
									.ToListAsync();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
				
			|||||||
@ -68,10 +68,10 @@ namespace Kyoo.Controllers
 | 
				
			|||||||
			foreach (PeopleLink peop in people)
 | 
								foreach (PeopleLink peop in people)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				string localPath = Path.Combine(root, peop.People.Slug + ".jpg");
 | 
									string localPath = Path.Combine(root, peop.People.Slug + ".jpg");
 | 
				
			||||||
				if (peop.People.ImgPrimary == null)
 | 
									if (peop.People.Poster == null)
 | 
				
			||||||
					continue;
 | 
										continue;
 | 
				
			||||||
				if (alwaysDownload || !File.Exists(localPath))
 | 
									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;
 | 
								return people;
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ using IdentityServer4.EntityFramework.Interfaces;
 | 
				
			|||||||
using IdentityServer4.EntityFramework.Options;
 | 
					using IdentityServer4.EntityFramework.Options;
 | 
				
			||||||
using Kyoo.Models;
 | 
					using Kyoo.Models;
 | 
				
			||||||
using Kyoo.Models.Exceptions;
 | 
					using Kyoo.Models.Exceptions;
 | 
				
			||||||
 | 
					using Kyoo.Models.Watch;
 | 
				
			||||||
using Microsoft.AspNetCore.Identity;
 | 
					using Microsoft.AspNetCore.Identity;
 | 
				
			||||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
 | 
					using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
@ -68,36 +69,45 @@ namespace Kyoo
 | 
				
			|||||||
		public DbSet<ProviderID> Providers { get; set; }
 | 
							public DbSet<ProviderID> Providers { get; set; }
 | 
				
			||||||
		public DbSet<MetadataID> MetadataIds { get; set; }
 | 
							public DbSet<MetadataID> MetadataIds { get; set; }
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		public DbSet<LibraryLink> LibraryLinks { get; set; }
 | 
							public DbSet<PeopleLink> PeopleRoles { get; set; }
 | 
				
			||||||
		public DbSet<CollectionLink> CollectionLinks { get; set; }
 | 
							
 | 
				
			||||||
		public DbSet<PeopleLink> PeopleLinks { 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.
 | 
							// 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<GenreLink> GenreLinks { get; set; }
 | 
				
			||||||
		public DbSet<ProviderLink> ProviderLinks { get; set; }
 | 
							public DbSet<ProviderLink> ProviderLinks { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		
 | 
							public DatabaseContext()
 | 
				
			||||||
		private readonly ValueConverter<IEnumerable<string>, string> _stringArrayConverter = 
 | 
							{
 | 
				
			||||||
			new ValueConverter<IEnumerable<string>, string>(
 | 
								NpgsqlConnection.GlobalTypeMapper.MapEnum<Status>();
 | 
				
			||||||
			arr => string.Join("|", arr),
 | 
								NpgsqlConnection.GlobalTypeMapper.MapEnum<ItemType>();
 | 
				
			||||||
			str => str.Split("|", StringSplitOptions.None));
 | 
								NpgsqlConnection.GlobalTypeMapper.MapEnum<StreamType>();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		private readonly ValueComparer<IEnumerable<string>> _stringArrayComparer = 
 | 
							private readonly ValueComparer<IEnumerable<string>> _stringArrayComparer = 
 | 
				
			||||||
			new ValueComparer<IEnumerable<string>>(
 | 
								new ValueComparer<IEnumerable<string>>(
 | 
				
			||||||
				(l1, l2) => l1.SequenceEqual(l2),
 | 
									(l1, l2) => l1.SequenceEqual(l2),
 | 
				
			||||||
				arr => arr.Aggregate(0, (i, s) => s.GetHashCode()));
 | 
									arr => arr.Aggregate(0, (i, s) => s.GetHashCode()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
		protected override void OnModelCreating(ModelBuilder modelBuilder)
 | 
							protected override void OnModelCreating(ModelBuilder modelBuilder)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			base.OnModelCreating(modelBuilder);
 | 
								base.OnModelCreating(modelBuilder);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			modelBuilder.Entity<Library>().Property(e => e.Paths)
 | 
								modelBuilder.HasPostgresEnum<Status>();
 | 
				
			||||||
				.HasConversion(_stringArrayConverter).Metadata
 | 
								modelBuilder.HasPostgresEnum<ItemType>();
 | 
				
			||||||
				.SetValueComparer(_stringArrayComparer);
 | 
								modelBuilder.HasPostgresEnum<StreamType>();
 | 
				
			||||||
			modelBuilder.Entity<Show>().Property(e => e.Aliases)
 | 
					
 | 
				
			||||||
				.HasConversion(_stringArrayConverter).Metadata
 | 
								modelBuilder.Entity<Library>()
 | 
				
			||||||
				.SetValueComparer(_stringArrayComparer);
 | 
									.Property(x => x.Paths)
 | 
				
			||||||
 | 
									.HasColumnType("text[]")
 | 
				
			||||||
 | 
									.Metadata.SetValueComparer(_stringArrayComparer);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								modelBuilder.Entity<Show>()
 | 
				
			||||||
 | 
									.Property(x => x.Aliases)
 | 
				
			||||||
 | 
									.HasColumnType("text[]")
 | 
				
			||||||
 | 
									.Metadata.SetValueComparer(_stringArrayComparer);
 | 
				
			||||||
 | 
								
 | 
				
			||||||
			
 | 
								
 | 
				
			||||||
			modelBuilder.Entity<Track>()
 | 
								modelBuilder.Entity<Track>()
 | 
				
			||||||
				.Property(t => t.IsDefault)
 | 
									.Property(t => t.IsDefault)
 | 
				
			||||||
@ -127,6 +137,7 @@ namespace Kyoo
 | 
				
			|||||||
			modelBuilder.Entity<PeopleLink>()
 | 
								modelBuilder.Entity<PeopleLink>()
 | 
				
			||||||
				.Ignore(x => x.Slug)
 | 
									.Ignore(x => x.Slug)
 | 
				
			||||||
				.Ignore(x => x.Name)
 | 
									.Ignore(x => x.Name)
 | 
				
			||||||
 | 
									.Ignore(x => x.Poster)
 | 
				
			||||||
				.Ignore(x => x.ExternalIDs);
 | 
									.Ignore(x => x.ExternalIDs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			modelBuilder.Entity<Genre>()
 | 
								modelBuilder.Entity<Genre>()
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
// <auto-generated />
 | 
					// <auto-generated />
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using Kyoo;
 | 
					using Kyoo;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
					using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
				
			||||||
@ -10,13 +11,16 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
 | 
				
			|||||||
namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
					namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    [DbContext(typeof(DatabaseContext))]
 | 
					    [DbContext(typeof(DatabaseContext))]
 | 
				
			||||||
    [Migration("20200803040029_Initial")]
 | 
					    [Migration("20200804172021_Initial")]
 | 
				
			||||||
    partial class Initial
 | 
					    partial class Initial
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        protected override void BuildTargetModel(ModelBuilder modelBuilder)
 | 
					        protected override void BuildTargetModel(ModelBuilder modelBuilder)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
#pragma warning disable 612, 618
 | 
					#pragma warning disable 612, 618
 | 
				
			||||||
            modelBuilder
 | 
					            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("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
 | 
				
			||||||
                .HasAnnotation("ProductVersion", "3.1.3")
 | 
					                .HasAnnotation("ProductVersion", "3.1.3")
 | 
				
			||||||
                .HasAnnotation("Relational:MaxIdentifierLength", 63);
 | 
					                .HasAnnotation("Relational:MaxIdentifierLength", 63);
 | 
				
			||||||
@ -167,8 +171,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                    b.Property<string>("Name")
 | 
					                    b.Property<string>("Name")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Paths")
 | 
					                    b.Property<IEnumerable<string>>("Paths")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text[]");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Slug")
 | 
					                    b.Property<string>("Slug")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
@ -262,10 +266,10 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                        .HasColumnType("integer")
 | 
					                        .HasColumnType("integer")
 | 
				
			||||||
                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
					                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("ImgPrimary")
 | 
					                    b.Property<string>("Name")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Name")
 | 
					                    b.Property<string>("Poster")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Slug")
 | 
					                    b.Property<string>("Slug")
 | 
				
			||||||
@ -304,7 +308,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    b.HasIndex("ShowID");
 | 
					                    b.HasIndex("ShowID");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.ToTable("PeopleLinks");
 | 
					                    b.ToTable("PeopleRoles");
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
 | 
					            modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
 | 
				
			||||||
@ -393,8 +397,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                        .HasColumnType("integer")
 | 
					                        .HasColumnType("integer")
 | 
				
			||||||
                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
					                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Aliases")
 | 
					                    b.Property<IEnumerable<string>>("Aliases")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text[]");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Backdrop")
 | 
					                    b.Property<string>("Backdrop")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
@ -8,6 +8,11 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        protected override void Up(MigrationBuilder migrationBuilder)
 | 
					        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(
 | 
					            migrationBuilder.CreateTable(
 | 
				
			||||||
                name: "Collections",
 | 
					                name: "Collections",
 | 
				
			||||||
                columns: table => new
 | 
					                columns: table => new
 | 
				
			||||||
@ -46,7 +51,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
 | 
					                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
 | 
				
			||||||
                    Slug = table.Column<string>(nullable: true),
 | 
					                    Slug = table.Column<string>(nullable: true),
 | 
				
			||||||
                    Name = 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 =>
 | 
					                constraints: table =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@ -61,7 +66,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
 | 
					                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
 | 
				
			||||||
                    Slug = table.Column<string>(nullable: true),
 | 
					                    Slug = table.Column<string>(nullable: true),
 | 
				
			||||||
                    Name = 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 =>
 | 
					                constraints: table =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@ -131,7 +136,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
 | 
					                        .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
 | 
				
			||||||
                    Slug = table.Column<string>(nullable: true),
 | 
					                    Slug = table.Column<string>(nullable: true),
 | 
				
			||||||
                    Title = 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),
 | 
					                    Path = table.Column<string>(nullable: true),
 | 
				
			||||||
                    Overview = table.Column<string>(nullable: true),
 | 
					                    Overview = table.Column<string>(nullable: true),
 | 
				
			||||||
                    Status = table.Column<int>(nullable: true),
 | 
					                    Status = table.Column<int>(nullable: true),
 | 
				
			||||||
@ -239,7 +244,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            migrationBuilder.CreateTable(
 | 
					            migrationBuilder.CreateTable(
 | 
				
			||||||
                name: "PeopleLinks",
 | 
					                name: "PeopleRoles",
 | 
				
			||||||
                columns: table => new
 | 
					                columns: table => new
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    ID = table.Column<int>(nullable: false)
 | 
					                    ID = table.Column<int>(nullable: false)
 | 
				
			||||||
@ -251,15 +256,15 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                },
 | 
					                },
 | 
				
			||||||
                constraints: table =>
 | 
					                constraints: table =>
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    table.PrimaryKey("PK_PeopleLinks", x => x.ID);
 | 
					                    table.PrimaryKey("PK_PeopleRoles", x => x.ID);
 | 
				
			||||||
                    table.ForeignKey(
 | 
					                    table.ForeignKey(
 | 
				
			||||||
                        name: "FK_PeopleLinks_People_PeopleID",
 | 
					                        name: "FK_PeopleRoles_People_PeopleID",
 | 
				
			||||||
                        column: x => x.PeopleID,
 | 
					                        column: x => x.PeopleID,
 | 
				
			||||||
                        principalTable: "People",
 | 
					                        principalTable: "People",
 | 
				
			||||||
                        principalColumn: "ID",
 | 
					                        principalColumn: "ID",
 | 
				
			||||||
                        onDelete: ReferentialAction.Cascade);
 | 
					                        onDelete: ReferentialAction.Cascade);
 | 
				
			||||||
                    table.ForeignKey(
 | 
					                    table.ForeignKey(
 | 
				
			||||||
                        name: "FK_PeopleLinks_Shows_ShowID",
 | 
					                        name: "FK_PeopleRoles_Shows_ShowID",
 | 
				
			||||||
                        column: x => x.ShowID,
 | 
					                        column: x => x.ShowID,
 | 
				
			||||||
                        principalTable: "Shows",
 | 
					                        principalTable: "Shows",
 | 
				
			||||||
                        principalColumn: "ID",
 | 
					                        principalColumn: "ID",
 | 
				
			||||||
@ -500,13 +505,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                unique: true);
 | 
					                unique: true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            migrationBuilder.CreateIndex(
 | 
					            migrationBuilder.CreateIndex(
 | 
				
			||||||
                name: "IX_PeopleLinks_PeopleID",
 | 
					                name: "IX_PeopleRoles_PeopleID",
 | 
				
			||||||
                table: "PeopleLinks",
 | 
					                table: "PeopleRoles",
 | 
				
			||||||
                column: "PeopleID");
 | 
					                column: "PeopleID");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            migrationBuilder.CreateIndex(
 | 
					            migrationBuilder.CreateIndex(
 | 
				
			||||||
                name: "IX_PeopleLinks_ShowID",
 | 
					                name: "IX_PeopleRoles_ShowID",
 | 
				
			||||||
                table: "PeopleLinks",
 | 
					                table: "PeopleRoles",
 | 
				
			||||||
                column: "ShowID");
 | 
					                column: "ShowID");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            migrationBuilder.CreateIndex(
 | 
					            migrationBuilder.CreateIndex(
 | 
				
			||||||
@ -569,7 +574,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                name: "MetadataIds");
 | 
					                name: "MetadataIds");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            migrationBuilder.DropTable(
 | 
					            migrationBuilder.DropTable(
 | 
				
			||||||
                name: "PeopleLinks");
 | 
					                name: "PeopleRoles");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            migrationBuilder.DropTable(
 | 
					            migrationBuilder.DropTable(
 | 
				
			||||||
                name: "ProviderLinks");
 | 
					                name: "ProviderLinks");
 | 
				
			||||||
@ -1,5 +1,6 @@
 | 
				
			|||||||
// <auto-generated />
 | 
					// <auto-generated />
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using Kyoo;
 | 
					using Kyoo;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore;
 | 
					using Microsoft.EntityFrameworkCore;
 | 
				
			||||||
using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
					using Microsoft.EntityFrameworkCore.Infrastructure;
 | 
				
			||||||
@ -15,6 +16,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
#pragma warning disable 612, 618
 | 
					#pragma warning disable 612, 618
 | 
				
			||||||
            modelBuilder
 | 
					            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("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
 | 
				
			||||||
                .HasAnnotation("ProductVersion", "3.1.3")
 | 
					                .HasAnnotation("ProductVersion", "3.1.3")
 | 
				
			||||||
                .HasAnnotation("Relational:MaxIdentifierLength", 63);
 | 
					                .HasAnnotation("Relational:MaxIdentifierLength", 63);
 | 
				
			||||||
@ -165,8 +169,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                    b.Property<string>("Name")
 | 
					                    b.Property<string>("Name")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Paths")
 | 
					                    b.Property<IEnumerable<string>>("Paths")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text[]");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Slug")
 | 
					                    b.Property<string>("Slug")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
@ -260,10 +264,10 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                        .HasColumnType("integer")
 | 
					                        .HasColumnType("integer")
 | 
				
			||||||
                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
					                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("ImgPrimary")
 | 
					                    b.Property<string>("Name")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Name")
 | 
					                    b.Property<string>("Poster")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Slug")
 | 
					                    b.Property<string>("Slug")
 | 
				
			||||||
@ -302,7 +306,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                    b.HasIndex("ShowID");
 | 
					                    b.HasIndex("ShowID");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.ToTable("PeopleLinks");
 | 
					                    b.ToTable("PeopleRoles");
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
 | 
					            modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
 | 
				
			||||||
@ -391,8 +395,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
 | 
				
			|||||||
                        .HasColumnType("integer")
 | 
					                        .HasColumnType("integer")
 | 
				
			||||||
                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
					                        .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Aliases")
 | 
					                    b.Property<IEnumerable<string>>("Aliases")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text[]");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    b.Property<string>("Backdrop")
 | 
					                    b.Property<string>("Backdrop")
 | 
				
			||||||
                        .HasColumnType("text");
 | 
					                        .HasColumnType("text");
 | 
				
			||||||
 | 
				
			|||||||
@ -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
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										93
									
								
								Kyoo/Views/API/PeopleApi.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								Kyoo/Views/API/PeopleApi.cs
									
									
									
									
									
										Normal 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});
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -6,13 +6,13 @@ using Microsoft.AspNetCore.Mvc;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace Kyoo.Api
 | 
					namespace Kyoo.Api
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	[Route("api/[controller]")]
 | 
						[Route("api/search")]
 | 
				
			||||||
	[ApiController]
 | 
						[ApiController]
 | 
				
			||||||
	public class SearchController : ControllerBase
 | 
						public class SearchApi : ControllerBase
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private readonly ILibraryManager _libraryManager;
 | 
							private readonly ILibraryManager _libraryManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public SearchController(ILibraryManager libraryManager)
 | 
							public SearchApi(ILibraryManager libraryManager)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			_libraryManager = libraryManager;
 | 
								_libraryManager = libraryManager;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -21,7 +21,7 @@ namespace Kyoo.Api
 | 
				
			|||||||
		[Authorize(Policy="Read")]
 | 
							[Authorize(Policy="Read")]
 | 
				
			||||||
		public async Task<ActionResult<SearchResult>> Search(string query)
 | 
							public async Task<ActionResult<SearchResult>> Search(string query)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			SearchResult result = new SearchResult
 | 
								return new SearchResult
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Query = query,
 | 
									Query = query,
 | 
				
			||||||
				Collections = await _libraryManager.SearchCollections(query),
 | 
									Collections = await _libraryManager.SearchCollections(query),
 | 
				
			||||||
@ -31,7 +31,6 @@ namespace Kyoo.Api
 | 
				
			|||||||
				Genres = await _libraryManager.SearchGenres(query),
 | 
									Genres = await _libraryManager.SearchGenres(query),
 | 
				
			||||||
				Studios = await _libraryManager.SearchStudios(query)
 | 
									Studios = await _libraryManager.SearchStudios(query)
 | 
				
			||||||
			};
 | 
								};
 | 
				
			||||||
			return result;
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1 +1 @@
 | 
				
			|||||||
Subproject commit de1b3b069aa4f920bd5248223eda151b1eedf541
 | 
					Subproject commit 3dad4b29d6565d08ef0bce1e450b5de65f6fac16
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user