mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-08 18:54:22 -04:00
commit
6ecc031c94
@ -1,58 +1,93 @@
|
|||||||
using Kyoo.Models;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Kyoo.Models;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
public interface ILibraryManager
|
public interface ILibraryManager
|
||||||
{
|
{
|
||||||
// Get by slug
|
// Get by slug
|
||||||
Library GetLibrary(string librarySlug);
|
Task<Library> GetLibrary(string slug);
|
||||||
Collection GetCollection(string slug);
|
Task<Collection> GetCollection(string slug);
|
||||||
Show GetShow(string slug);
|
Task<Show> GetShow(string slug);
|
||||||
Season GetSeason(string showSlug, long seasonNumber);
|
Task<Season> GetSeason(string showSlug, int seasonNumber);
|
||||||
Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber);
|
Task<Episode> GetEpisode(string showSlug, int seasonNumber, int episodeNumber);
|
||||||
Episode GetMovieEpisode(string movieSlug);
|
Task<Episode> GetMovieEpisode(string movieSlug);
|
||||||
Genre GetGenre(string slug);
|
Task<Track> GetTrack(int id);
|
||||||
Studio GetStudio(string slug);
|
Task<Track> GetTrack(int episodeID, string language, bool isForced);
|
||||||
People GetPeople(string slug);
|
Task<Genre> GetGenre(string slug);
|
||||||
ProviderID GetProvider(string name);
|
Task<Studio> GetStudio(string slug);
|
||||||
|
Task<People> GetPeople(string slug);
|
||||||
|
|
||||||
|
// Get by relations
|
||||||
|
Task<ICollection<Season>> GetSeasons(int showID);
|
||||||
|
Task<ICollection<Season>> GetSeasons(string showSlug);
|
||||||
|
|
||||||
|
Task<ICollection<Episode>> GetEpisodes(int showID, int seasonNumber);
|
||||||
|
Task<ICollection<Episode>> GetEpisodes(string showSlug, int seasonNumber);
|
||||||
|
Task<ICollection<Episode>> GetEpisodes(int seasonID);
|
||||||
|
|
||||||
|
|
||||||
|
// Helpers
|
||||||
|
Task<Show> GetShowByPath(string path);
|
||||||
|
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
||||||
|
Task AddShowLink([NotNull] Show show, Library library, Collection collection);
|
||||||
|
|
||||||
// Get all
|
// Get all
|
||||||
IEnumerable<Library> GetLibraries();
|
Task<ICollection<Library>> GetLibraries();
|
||||||
IEnumerable<Collection> GetCollections();
|
Task<ICollection<Collection>> GetCollections();
|
||||||
IEnumerable<Show> GetShows();
|
Task<ICollection<Show>> GetShows();
|
||||||
IEnumerable<Episode> GetEpisodes();
|
Task<ICollection<Season>> GetSeasons();
|
||||||
IEnumerable<Track> GetTracks();
|
Task<ICollection<Episode>> GetEpisodes();
|
||||||
IEnumerable<Studio> GetStudios();
|
Task<ICollection<Track>> GetTracks();
|
||||||
IEnumerable<People> GetPeoples();
|
Task<ICollection<Studio>> GetStudios();
|
||||||
IEnumerable<Genre> GetGenres();
|
Task<ICollection<People>> GetPeoples();
|
||||||
|
Task<ICollection<Genre>> GetGenres();
|
||||||
|
Task<ICollection<ProviderID>> GetProviders();
|
||||||
|
|
||||||
// Search
|
// Search
|
||||||
IEnumerable<Collection> SearchCollections(string searchQuery);
|
Task<ICollection<Library>> SearchLibraries(string searchQuery);
|
||||||
IEnumerable<Show> SearchShows(string searchQuery);
|
Task<ICollection<Collection>> SearchCollections(string searchQuery);
|
||||||
IEnumerable<Episode> SearchEpisodes(string searchQuery);
|
Task<ICollection<Show>> SearchShows(string searchQuery);
|
||||||
IEnumerable<Genre> SearchGenres(string searchQuery);
|
Task<ICollection<Season>> SearchSeasons(string searchQuery);
|
||||||
IEnumerable<Studio> SearchStudios(string searchQuery);
|
Task<ICollection<Episode>> SearchEpisodes(string searchQuery);
|
||||||
IEnumerable<People> SearchPeople(string searchQuery);
|
Task<ICollection<Genre>> SearchGenres(string searchQuery);
|
||||||
|
Task<ICollection<Studio>> SearchStudios(string searchQuery);
|
||||||
|
Task<ICollection<People>> SearchPeople(string searchQuery);
|
||||||
|
|
||||||
// Other get helpers
|
|
||||||
Show GetShowByPath(string path);
|
|
||||||
IEnumerable<string> GetLibrariesPath();
|
|
||||||
IEnumerable<Episode> GetEpisodes(string showSlug, long seasonNumber);
|
|
||||||
|
|
||||||
//Register values
|
//Register values
|
||||||
void Register(object obj);
|
Task RegisterLibrary(Library library);
|
||||||
Task Edit(object obj, bool resetOld);
|
Task RegisterCollection(Collection collection);
|
||||||
void RegisterShowLinks(Library library, Collection collection, Show show);
|
Task RegisterShow(Show show);
|
||||||
Task SaveChanges();
|
Task RegisterSeason(Season season);
|
||||||
|
Task RegisterEpisode(Episode episode);
|
||||||
|
Task RegisterTrack(Track track);
|
||||||
|
Task RegisterGenre(Genre genre);
|
||||||
|
Task RegisterStudio(Studio studio);
|
||||||
|
Task RegisterPeople(People people);
|
||||||
|
|
||||||
// Validate values
|
// Edit values
|
||||||
IEnumerable<MetadataID> Validate(IEnumerable<MetadataID> id);
|
Task EditLibrary(Library library, bool resetOld);
|
||||||
|
Task EditCollection(Collection collection, bool resetOld);
|
||||||
|
Task EditShow(Show show, bool resetOld);
|
||||||
|
Task EditSeason(Season season, bool resetOld);
|
||||||
|
Task EditEpisode(Episode episode, bool resetOld);
|
||||||
|
Task EditTrack(Track track, bool resetOld);
|
||||||
|
Task EditGenre(Genre genre, bool resetOld);
|
||||||
|
Task EditStudio(Studio studio, bool resetOld);
|
||||||
|
Task EditPeople(People people, bool resetOld);
|
||||||
|
|
||||||
|
|
||||||
// Remove values
|
// Delete values
|
||||||
void RemoveShow(Show show);
|
Task DelteLibrary(Library library);
|
||||||
void RemoveSeason(Season season);
|
Task DeleteCollection(Collection collection);
|
||||||
void RemoveEpisode(Episode episode);
|
Task DeleteShow(Show show);
|
||||||
|
Task DeleteSeason(Season season);
|
||||||
|
Task DeleteEpisode(Episode episode);
|
||||||
|
Task DeleteTrack(Track track);
|
||||||
|
Task DeleteGenre(Genre genre);
|
||||||
|
Task DeleteStudio(Studio studio);
|
||||||
|
Task DeletePeople(People people);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ namespace Kyoo.Controllers
|
|||||||
Task<IEnumerable<Show>> SearchShows(string showName, bool isMovie);
|
Task<IEnumerable<Show>> SearchShows(string showName, bool isMovie);
|
||||||
Task<IEnumerable<PeopleLink>> GetPeople(Show show);
|
Task<IEnumerable<PeopleLink>> GetPeople(Show show);
|
||||||
|
|
||||||
Task<Season> GetSeason(Show show, long seasonNumber);
|
Task<Season> GetSeason(Show show, int seasonNumber);
|
||||||
|
|
||||||
Task<Episode> GetEpisode(Show show, long seasonNumber, long episodeNumber, long absoluteNumber);
|
Task<Episode> GetEpisode(Show show, int seasonNumber, int episodeNumber, int absoluteNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,8 +10,8 @@ namespace Kyoo.Controllers
|
|||||||
Task<Show> CompleteShow(Show show, Library library);
|
Task<Show> CompleteShow(Show show, Library library);
|
||||||
Task<Show> SearchShow(string showName, bool isMovie, Library library);
|
Task<Show> SearchShow(string showName, bool isMovie, Library library);
|
||||||
Task<IEnumerable<Show>> SearchShows(string showName, bool isMovie, Library library);
|
Task<IEnumerable<Show>> SearchShows(string showName, bool isMovie, Library library);
|
||||||
Task<Season> GetSeason(Show show, long seasonNumber, Library library);
|
Task<Season> GetSeason(Show show, int seasonNumber, Library library);
|
||||||
Task<Episode> GetEpisode(Show show, string episodePath, long seasonNumber, long episodeNumber, long absoluteNumber, Library library);
|
Task<Episode> GetEpisode(Show show, string episodePath, int seasonNumber, int episodeNumber, int absoluteNumber, Library library);
|
||||||
Task<IEnumerable<PeopleLink>> GetPeople(Show show, Library library);
|
Task<IEnumerable<PeopleLink>> GetPeople(Show show, Library library);
|
||||||
}
|
}
|
||||||
}
|
}
|
53
Kyoo.Common/Controllers/IRepository.cs
Normal file
53
Kyoo.Common/Controllers/IRepository.cs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
|
using Kyoo.Models;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public interface IRepository<T>
|
||||||
|
{
|
||||||
|
Task<T> Get(int id);
|
||||||
|
Task<T> Get(string slug);
|
||||||
|
Task<ICollection<T>> Search(string query);
|
||||||
|
Task<ICollection<T>> GetAll();
|
||||||
|
Task<int> Create([NotNull] T obj);
|
||||||
|
Task<int> CreateIfNotExists([NotNull] T obj);
|
||||||
|
Task Edit([NotNull] T edited, bool resetOld);
|
||||||
|
Task Delete(T obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IShowRepository : IRepository<Show>
|
||||||
|
{
|
||||||
|
Task<Show> GetByPath(string path);
|
||||||
|
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ISeasonRepository : IRepository<Season>
|
||||||
|
{
|
||||||
|
Task<Season> Get(string showSlug, int seasonNumber);
|
||||||
|
|
||||||
|
Task<ICollection<Season>> GetSeasons(int showID);
|
||||||
|
Task<ICollection<Season>> GetSeasons(string showSlug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IEpisodeRepository : IRepository<Episode>
|
||||||
|
{
|
||||||
|
Task<Episode> Get(string showSlug, int seasonNumber, int episodeNumber);
|
||||||
|
|
||||||
|
Task<ICollection<Episode>> GetEpisodes(int showID, int seasonNumber);
|
||||||
|
Task<ICollection<Episode>> GetEpisodes(string showSlug, int seasonNumber);
|
||||||
|
Task<ICollection<Episode>> GetEpisodes(int seasonID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface ITrackRepository : IRepository<Track>
|
||||||
|
{
|
||||||
|
Task<Track> Get(int episodeID, string languageTag, bool isForced);
|
||||||
|
}
|
||||||
|
public interface ILibraryRepository : IRepository<Library> {}
|
||||||
|
public interface ICollectionRepository : IRepository<Collection> {}
|
||||||
|
public interface IGenreRepository : IRepository<Genre> {}
|
||||||
|
public interface IStudioRepository : IRepository<Studio> {}
|
||||||
|
public interface IPeopleRepository : IRepository<People> {}
|
||||||
|
public interface IProviderRepository : IRepository<ProviderID> {}
|
||||||
|
}
|
@ -11,7 +11,7 @@
|
|||||||
<Company>SDG</Company>
|
<Company>SDG</Company>
|
||||||
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
<PackageLicenseExpression>GPL-3.0-or-later</PackageLicenseExpression>
|
||||||
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
|
||||||
<PackageVersion>1.0.20</PackageVersion>
|
<PackageVersion>1.0.21</PackageVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -7,7 +7,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Collection
|
public class Collection
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] 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; }
|
||||||
public string Poster { get; set; }
|
public string Poster { get; set; }
|
||||||
|
@ -2,10 +2,10 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class CollectionLink
|
public class CollectionLink
|
||||||
{
|
{
|
||||||
public long ID { get; set; }
|
public int ID { get; set; }
|
||||||
public long? CollectionID { get; set; }
|
public int? CollectionID { get; set; }
|
||||||
public virtual Collection Collection { get; set; }
|
public virtual Collection Collection { get; set; }
|
||||||
public long ShowID { get; set; }
|
public int ShowID { get; set; }
|
||||||
public virtual Show Show { get; set; }
|
public virtual Show Show { get; set; }
|
||||||
|
|
||||||
public CollectionLink() { }
|
public CollectionLink() { }
|
||||||
|
@ -6,21 +6,21 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Episode
|
public class Episode
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
[JsonIgnore] public long ShowID { get; set; }
|
[JsonIgnore] public int ShowID { get; set; }
|
||||||
[JsonIgnore] public virtual Show Show { get; set; }
|
[JsonIgnore] public virtual Show Show { get; set; }
|
||||||
[JsonIgnore] public long? SeasonID { get; set; }
|
[JsonIgnore] public int? SeasonID { get; set; }
|
||||||
[JsonIgnore] public virtual Season Season { get; set; }
|
[JsonIgnore] public virtual Season Season { get; set; }
|
||||||
|
|
||||||
public long SeasonNumber { get; set; }
|
public int SeasonNumber { get; set; }
|
||||||
public long EpisodeNumber { get; set; }
|
public int EpisodeNumber { get; set; }
|
||||||
public long AbsoluteNumber { get; set; }
|
public int AbsoluteNumber { get; set; }
|
||||||
[JsonIgnore] public string Path { get; set; }
|
[JsonIgnore] public string Path { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public DateTime? ReleaseDate { get; set; }
|
public DateTime? ReleaseDate { get; set; }
|
||||||
|
|
||||||
public long Runtime { get; set; } //This runtime variable should be in minutes
|
public int Runtime { get; set; } //This runtime variable should be in minutes
|
||||||
|
|
||||||
[JsonIgnore] public string ImgPrimary { get; set; }
|
[JsonIgnore] public string ImgPrimary { get; set; }
|
||||||
public virtual IEnumerable<MetadataID> ExternalIDs { get; set; }
|
public virtual IEnumerable<MetadataID> ExternalIDs { get; set; }
|
||||||
@ -42,13 +42,13 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public Episode() { }
|
public Episode() { }
|
||||||
|
|
||||||
public Episode(long seasonNumber,
|
public Episode(int seasonNumber,
|
||||||
long episodeNumber,
|
int episodeNumber,
|
||||||
long absoluteNumber,
|
int absoluteNumber,
|
||||||
string title,
|
string title,
|
||||||
string overview,
|
string overview,
|
||||||
DateTime? releaseDate,
|
DateTime? releaseDate,
|
||||||
long runtime,
|
int runtime,
|
||||||
string imgPrimary,
|
string imgPrimary,
|
||||||
IEnumerable<MetadataID> externalIDs)
|
IEnumerable<MetadataID> externalIDs)
|
||||||
{
|
{
|
||||||
@ -63,16 +63,16 @@ namespace Kyoo.Models
|
|||||||
ExternalIDs = externalIDs;
|
ExternalIDs = externalIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode(long showID,
|
public Episode(int showID,
|
||||||
long seasonID,
|
int seasonID,
|
||||||
long seasonNumber,
|
int seasonNumber,
|
||||||
long episodeNumber,
|
int episodeNumber,
|
||||||
long absoluteNumber,
|
int absoluteNumber,
|
||||||
string path,
|
string path,
|
||||||
string title,
|
string title,
|
||||||
string overview,
|
string overview,
|
||||||
DateTime? releaseDate,
|
DateTime? releaseDate,
|
||||||
long runtime,
|
int runtime,
|
||||||
string imgPrimary,
|
string imgPrimary,
|
||||||
IEnumerable<MetadataID> externalIDs)
|
IEnumerable<MetadataID> externalIDs)
|
||||||
{
|
{
|
||||||
@ -90,7 +90,7 @@ namespace Kyoo.Models
|
|||||||
ExternalIDs = externalIDs;
|
ExternalIDs = externalIDs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetSlug(string showSlug, long seasonNumber, long episodeNumber)
|
public static string GetSlug(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
return showSlug + "-s" + seasonNumber + "e" + episodeNumber;
|
return showSlug + "-s" + seasonNumber + "e" + episodeNumber;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Genre
|
public class Genre
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] 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; }
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ namespace Kyoo.Models
|
|||||||
Name = name;
|
Name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Genre(long id, string slug, string name)
|
public Genre(int id, string slug, string name)
|
||||||
{
|
{
|
||||||
ID = id;
|
ID = id;
|
||||||
Slug = slug;
|
Slug = slug;
|
||||||
|
@ -2,9 +2,9 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class GenreLink
|
public class GenreLink
|
||||||
{
|
{
|
||||||
public long ShowID { get; set; }
|
public int ShowID { get; set; }
|
||||||
public virtual Show Show { get; set; }
|
public virtual Show Show { get; set; }
|
||||||
public long GenreID { get; set; }
|
public int GenreID { get; set; }
|
||||||
public virtual Genre Genre { get; set; }
|
public virtual Genre Genre { get; set; }
|
||||||
|
|
||||||
public GenreLink() {}
|
public GenreLink() {}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System.Collections;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Kyoo.Models.Attributes;
|
using Kyoo.Models.Attributes;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
@ -8,7 +7,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Library
|
public class Library
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] 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; }
|
||||||
public IEnumerable<string> Paths { get; set; }
|
public IEnumerable<string> Paths { get; set; }
|
||||||
|
@ -2,12 +2,12 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class LibraryLink
|
public class LibraryLink
|
||||||
{
|
{
|
||||||
public long ID { get; set; }
|
public int ID { get; set; }
|
||||||
public long LibraryID { get; set; }
|
public int LibraryID { get; set; }
|
||||||
public virtual Library Library { get; set; }
|
public virtual Library Library { get; set; }
|
||||||
public long? ShowID { get; set; }
|
public int? ShowID { get; set; }
|
||||||
public virtual Show Show { get; set; }
|
public virtual Show Show { get; set; }
|
||||||
public long? CollectionID { get; set; }
|
public int? CollectionID { get; set; }
|
||||||
public virtual Collection Collection { get; set; }
|
public virtual Collection Collection { get; set; }
|
||||||
|
|
||||||
public LibraryLink() { }
|
public LibraryLink() { }
|
||||||
|
@ -4,20 +4,20 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class MetadataID
|
public class MetadataID
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
[JsonIgnore] public long ProviderID { get; set; }
|
[JsonIgnore] public int ProviderID { get; set; }
|
||||||
public virtual ProviderID Provider {get; set; }
|
public virtual ProviderID Provider {get; set; }
|
||||||
|
|
||||||
[JsonIgnore] public long? ShowID { get; set; }
|
[JsonIgnore] public int? ShowID { get; set; }
|
||||||
[JsonIgnore] public virtual Show Show { get; set; }
|
[JsonIgnore] public virtual Show Show { get; set; }
|
||||||
|
|
||||||
[JsonIgnore] public long? EpisodeID { get; set; }
|
[JsonIgnore] public int? EpisodeID { get; set; }
|
||||||
[JsonIgnore] public virtual Episode Episode { get; set; }
|
[JsonIgnore] public virtual Episode Episode { get; set; }
|
||||||
|
|
||||||
[JsonIgnore] public long? SeasonID { get; set; }
|
[JsonIgnore] public int? SeasonID { get; set; }
|
||||||
[JsonIgnore] public virtual Season Season { get; set; }
|
[JsonIgnore] public virtual Season Season { get; set; }
|
||||||
|
|
||||||
[JsonIgnore] public long? PeopleID { get; set; }
|
[JsonIgnore] public int? PeopleID { get; set; }
|
||||||
[JsonIgnore] public virtual People People { get; set; }
|
[JsonIgnore] public virtual People People { get; set; }
|
||||||
|
|
||||||
public string DataID { get; set; }
|
public string DataID { get; set; }
|
||||||
|
@ -6,7 +6,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class People
|
public class People
|
||||||
{
|
{
|
||||||
public long 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; }
|
[JsonIgnore] public string ImgPrimary { get; set; }
|
||||||
|
@ -5,8 +5,8 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class PeopleLink
|
public class PeopleLink
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
[JsonIgnore] public long PeopleID { get; set; }
|
[JsonIgnore] public int PeopleID { get; set; }
|
||||||
[JsonIgnore] public virtual People People { get; set; }
|
[JsonIgnore] public virtual People People { get; set; }
|
||||||
|
|
||||||
public string Slug
|
public string Slug
|
||||||
@ -27,7 +27,7 @@ namespace Kyoo.Models
|
|||||||
set => People.ExternalIDs = value;
|
set => People.ExternalIDs = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
[JsonIgnore] public long ShowID { get; set; }
|
[JsonIgnore] public int ShowID { get; set; }
|
||||||
[JsonIgnore] public virtual Show Show { get; set; }
|
[JsonIgnore] public virtual Show Show { get; set; }
|
||||||
public string Role { get; set; }
|
public string Role { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
|
@ -4,13 +4,13 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class ProviderID
|
public class ProviderID
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Logo { get; set; }
|
public string Logo { get; set; }
|
||||||
|
|
||||||
public ProviderID() { }
|
public ProviderID() { }
|
||||||
|
|
||||||
public ProviderID(long id, string name, string logo)
|
public ProviderID(int id, string name, string logo)
|
||||||
{
|
{
|
||||||
ID = id;
|
ID = id;
|
||||||
Name = name;
|
Name = name;
|
||||||
|
@ -4,10 +4,10 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class ProviderLink
|
public class ProviderLink
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
[JsonIgnore] public long ProviderID { get; set; }
|
[JsonIgnore] public int ProviderID { get; set; }
|
||||||
[JsonIgnore] public virtual ProviderID Provider { get; set; }
|
[JsonIgnore] public virtual ProviderID Provider { get; set; }
|
||||||
[JsonIgnore] public long? LibraryID { get; set; }
|
[JsonIgnore] public int? LibraryID { get; set; }
|
||||||
[JsonIgnore] public virtual Library Library { get; set; }
|
[JsonIgnore] public virtual Library Library { get; set; }
|
||||||
|
|
||||||
public ProviderLink() { }
|
public ProviderLink() { }
|
||||||
|
@ -5,15 +5,15 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Season
|
public class Season
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
[JsonIgnore] public long ShowID { get; set; }
|
[JsonIgnore] public int ShowID { get; set; }
|
||||||
|
|
||||||
public long SeasonNumber { get; set; } = -1;
|
public int SeasonNumber { get; set; } = -1;
|
||||||
|
|
||||||
public string Slug => $"{Show.Title}-s{SeasonNumber}";
|
public string Slug => $"{Show.Slug}-s{SeasonNumber}";
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public long? Year { get; set; }
|
public int? Year { get; set; }
|
||||||
|
|
||||||
[JsonIgnore] public string ImgPrimary { get; set; }
|
[JsonIgnore] public string ImgPrimary { get; set; }
|
||||||
public virtual IEnumerable<MetadataID> ExternalIDs { get; set; }
|
public virtual IEnumerable<MetadataID> ExternalIDs { get; set; }
|
||||||
@ -23,11 +23,11 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public Season() { }
|
public Season() { }
|
||||||
|
|
||||||
public Season(long showID,
|
public Season(int showID,
|
||||||
long seasonNumber,
|
int seasonNumber,
|
||||||
string title,
|
string title,
|
||||||
string overview,
|
string overview,
|
||||||
long? year,
|
int? year,
|
||||||
string imgPrimary,
|
string imgPrimary,
|
||||||
IEnumerable<MetadataID> externalIDs)
|
IEnumerable<MetadataID> externalIDs)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Show : IOnMerge
|
public class Show : IOnMerge
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
|
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
@ -17,8 +17,8 @@ namespace Kyoo.Models
|
|||||||
public Status? Status { get; set; }
|
public Status? Status { get; set; }
|
||||||
public string TrailerUrl { get; set; }
|
public string TrailerUrl { get; set; }
|
||||||
|
|
||||||
public long? StartYear { get; set; }
|
public int? StartYear { get; set; }
|
||||||
public long? EndYear { get; set; }
|
public int? EndYear { get; set; }
|
||||||
|
|
||||||
public string Poster { get; set; }
|
public string Poster { get; set; }
|
||||||
public string Logo { get; set; }
|
public string Logo { get; set; }
|
||||||
@ -36,6 +36,7 @@ namespace Kyoo.Models
|
|||||||
set => GenreLinks = value?.Select(x => new GenreLink(this, x)).ToList();
|
set => GenreLinks = value?.Select(x => new GenreLink(this, x)).ToList();
|
||||||
}
|
}
|
||||||
[NotMergable] [JsonIgnore] public virtual IEnumerable<GenreLink> GenreLinks { get; set; }
|
[NotMergable] [JsonIgnore] public virtual IEnumerable<GenreLink> GenreLinks { get; set; }
|
||||||
|
[JsonIgnore] public int? StudioID { get; set; }
|
||||||
public virtual Studio Studio { get; set; }
|
public virtual Studio Studio { get; set; }
|
||||||
[JsonIgnore] public virtual IEnumerable<PeopleLink> People { get; set; }
|
[JsonIgnore] public virtual IEnumerable<PeopleLink> People { get; set; }
|
||||||
[JsonIgnore] public virtual IEnumerable<Season> Seasons { get; set; }
|
[JsonIgnore] public virtual IEnumerable<Season> Seasons { get; set; }
|
||||||
@ -50,8 +51,8 @@ namespace Kyoo.Models
|
|||||||
string trailerUrl,
|
string trailerUrl,
|
||||||
IEnumerable<Genre> genres,
|
IEnumerable<Genre> genres,
|
||||||
Status? status,
|
Status? status,
|
||||||
long? startYear,
|
int? startYear,
|
||||||
long? endYear,
|
int? endYear,
|
||||||
IEnumerable<MetadataID> externalIDs)
|
IEnumerable<MetadataID> externalIDs)
|
||||||
{
|
{
|
||||||
Slug = slug;
|
Slug = slug;
|
||||||
@ -75,8 +76,8 @@ namespace Kyoo.Models
|
|||||||
string overview,
|
string overview,
|
||||||
string trailerUrl,
|
string trailerUrl,
|
||||||
Status? status,
|
Status? status,
|
||||||
long? startYear,
|
int? startYear,
|
||||||
long? endYear,
|
int? endYear,
|
||||||
string poster,
|
string poster,
|
||||||
string logo,
|
string logo,
|
||||||
string backdrop,
|
string backdrop,
|
||||||
|
@ -5,7 +5,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class Studio
|
public class Studio
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] 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; }
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ namespace Kyoo.Models
|
|||||||
public bool RunOnStartup { get; }
|
public bool RunOnStartup { get; }
|
||||||
public int Priority { get; }
|
public int Priority { get; }
|
||||||
public Task Run(IServiceProvider serviceProvider, CancellationToken cancellationToken, string arguments = null);
|
public Task Run(IServiceProvider serviceProvider, CancellationToken cancellationToken, string arguments = null);
|
||||||
public IEnumerable<string> GetPossibleParameters();
|
public Task<IEnumerable<string>> GetPossibleParameters();
|
||||||
public int? Progress();
|
public int? Progress();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -55,8 +55,8 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public class Track : Stream
|
public class Track : Stream
|
||||||
{
|
{
|
||||||
[JsonIgnore] public long ID { get; set; }
|
[JsonIgnore] public int ID { get; set; }
|
||||||
[JsonIgnore] public long EpisodeID { get; set; }
|
[JsonIgnore] public int EpisodeID { get; set; }
|
||||||
public bool IsDefault
|
public bool IsDefault
|
||||||
{
|
{
|
||||||
get => isDefault;
|
get => isDefault;
|
||||||
|
@ -7,12 +7,12 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public class WatchItem
|
public class WatchItem
|
||||||
{
|
{
|
||||||
[JsonIgnore] public readonly long EpisodeID = -1;
|
[JsonIgnore] public readonly int EpisodeID = -1;
|
||||||
|
|
||||||
public string ShowTitle;
|
public string ShowTitle;
|
||||||
public string ShowSlug;
|
public string ShowSlug;
|
||||||
public long SeasonNumber;
|
public int SeasonNumber;
|
||||||
public long EpisodeNumber;
|
public int EpisodeNumber;
|
||||||
public string Title;
|
public string Title;
|
||||||
public string Link;
|
public string Link;
|
||||||
public DateTime? ReleaseDate;
|
public DateTime? ReleaseDate;
|
||||||
@ -28,11 +28,11 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public WatchItem() { }
|
public WatchItem() { }
|
||||||
|
|
||||||
public WatchItem(long episodeID,
|
public WatchItem(int episodeID,
|
||||||
string showTitle,
|
string showTitle,
|
||||||
string showSlug,
|
string showSlug,
|
||||||
long seasonNumber,
|
int seasonNumber,
|
||||||
long episodeNumber,
|
int episodeNumber,
|
||||||
string title,
|
string title,
|
||||||
DateTime? releaseDate,
|
DateTime? releaseDate,
|
||||||
string path)
|
string path)
|
||||||
@ -50,11 +50,11 @@ namespace Kyoo.Models
|
|||||||
Link = Episode.GetSlug(ShowSlug, seasonNumber, episodeNumber);
|
Link = Episode.GetSlug(ShowSlug, seasonNumber, episodeNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public WatchItem(long episodeID,
|
public WatchItem(int episodeID,
|
||||||
string showTitle,
|
string showTitle,
|
||||||
string showSlug,
|
string showSlug,
|
||||||
long seasonNumber,
|
int seasonNumber,
|
||||||
long episodeNumber,
|
int episodeNumber,
|
||||||
string title,
|
string title,
|
||||||
DateTime? releaseDate,
|
DateTime? releaseDate,
|
||||||
string path,
|
string path,
|
||||||
|
@ -1,394 +1,366 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Exceptions;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
public class LibraryManager : ILibraryManager
|
public class LibraryManager : ILibraryManager
|
||||||
{
|
{
|
||||||
private const int MaxSaveRetry = 3;
|
private readonly ILibraryRepository _libraries;
|
||||||
private readonly DatabaseContext _database;
|
private readonly ICollectionRepository _collections;
|
||||||
|
private readonly IShowRepository _shows;
|
||||||
|
private readonly ISeasonRepository _seasons;
|
||||||
|
private readonly IEpisodeRepository _episodes;
|
||||||
|
private readonly ITrackRepository _tracks;
|
||||||
|
private readonly IGenreRepository _genres;
|
||||||
|
private readonly IStudioRepository _studios;
|
||||||
|
private readonly IPeopleRepository _people;
|
||||||
|
private readonly IProviderRepository _providers;
|
||||||
|
|
||||||
|
public LibraryManager(ILibraryRepository libraries,
|
||||||
public LibraryManager(DatabaseContext database)
|
ICollectionRepository collections,
|
||||||
|
IShowRepository shows,
|
||||||
|
ISeasonRepository seasons,
|
||||||
|
IEpisodeRepository episodes,
|
||||||
|
ITrackRepository tracks,
|
||||||
|
IGenreRepository genres,
|
||||||
|
IStudioRepository studios,
|
||||||
|
IProviderRepository providers,
|
||||||
|
IPeopleRepository people)
|
||||||
{
|
{
|
||||||
_database = database;
|
_libraries = libraries;
|
||||||
|
_collections = collections;
|
||||||
|
_shows = shows;
|
||||||
|
_seasons = seasons;
|
||||||
|
_episodes = episodes;
|
||||||
|
_tracks = tracks;
|
||||||
|
_genres = genres;
|
||||||
|
_studios = studios;
|
||||||
|
_providers = providers;
|
||||||
|
_people = people;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region GetBySlug
|
public Task<Library> GetLibrary(string slug)
|
||||||
public Library GetLibrary(string librarySlug)
|
|
||||||
{
|
{
|
||||||
return _database.Libraries.FirstOrDefault(library => library.Slug == librarySlug);
|
return _libraries.Get(slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Collection> GetCollection(string slug)
|
||||||
|
{
|
||||||
|
return _collections.Get(slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Show> GetShow(string slug)
|
||||||
|
{
|
||||||
|
return _shows.Get(slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Season> GetSeason(string showSlug, int seasonNumber)
|
||||||
|
{
|
||||||
|
return _seasons.Get(showSlug, seasonNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Episode> GetEpisode(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
|
{
|
||||||
|
return _episodes.Get(showSlug, seasonNumber, episodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Episode> GetMovieEpisode(string movieSlug)
|
||||||
|
{
|
||||||
|
return _episodes.Get(movieSlug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Track> GetTrack(int id)
|
||||||
|
{
|
||||||
|
return _tracks.Get(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Collection GetCollection(string slug)
|
public Task<Track> GetTrack(int episodeID, string language, bool isForced)
|
||||||
{
|
{
|
||||||
return _database.Collections.FirstOrDefault(col => col.Slug == slug);
|
return _tracks.Get(episodeID, language, isForced);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Show GetShow(string slug)
|
public Task<Genre> GetGenre(string slug)
|
||||||
{
|
{
|
||||||
return _database.Shows.FirstOrDefault(show => show.Slug == slug);
|
return _genres.Get(slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Season GetSeason(string showSlug, long seasonNumber)
|
public Task<Studio> GetStudio(string slug)
|
||||||
{
|
{
|
||||||
return _database.Seasons.FirstOrDefault(x => x.Show.Slug == showSlug && x.SeasonNumber == seasonNumber);
|
return _studios.Get(slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber)
|
public Task<People> GetPeople(string slug)
|
||||||
{
|
{
|
||||||
return _database.Episodes.FirstOrDefault(x => x.EpisodeNumber == episodeNumber
|
return _people.Get(slug);
|
||||||
&& x.SeasonNumber == seasonNumber
|
}
|
||||||
&& x.Show.Slug == showSlug);
|
|
||||||
|
public Task<ICollection<Library>> GetLibraries()
|
||||||
|
{
|
||||||
|
return _libraries.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Collection>> GetCollections()
|
||||||
|
{
|
||||||
|
return _collections.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Show>> GetShows()
|
||||||
|
{
|
||||||
|
return _shows.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Season>> GetSeasons()
|
||||||
|
{
|
||||||
|
return _seasons.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Episode>> GetEpisodes()
|
||||||
|
{
|
||||||
|
return _episodes.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Track>> GetTracks()
|
||||||
|
{
|
||||||
|
return _tracks.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Studio>> GetStudios()
|
||||||
|
{
|
||||||
|
return _studios.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<People>> GetPeoples()
|
||||||
|
{
|
||||||
|
return _people.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Genre>> GetGenres()
|
||||||
|
{
|
||||||
|
return _genres.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<ProviderID>> GetProviders()
|
||||||
|
{
|
||||||
|
return _providers.GetAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Season>> GetSeasons(int showID)
|
||||||
|
{
|
||||||
|
return _seasons.GetSeasons(showID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Season>> GetSeasons(string showSlug)
|
||||||
|
{
|
||||||
|
return _seasons.GetSeasons(showSlug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Episode>> GetEpisodes(int showID, int seasonNumber)
|
||||||
|
{
|
||||||
|
return _episodes.GetEpisodes(showID, seasonNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Episode>> GetEpisodes(string showSlug, int seasonNumber)
|
||||||
|
{
|
||||||
|
return _episodes.GetEpisodes(showSlug, seasonNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Episode>> GetEpisodes(int seasonID)
|
||||||
|
{
|
||||||
|
return _episodes.GetEpisodes(seasonID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Show> GetShowByPath(string path)
|
||||||
|
{
|
||||||
|
return _shows.GetByPath(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task AddShowLink(int showID, int? libraryID, int? collectionID)
|
||||||
|
{
|
||||||
|
return _shows.AddShowLink(showID, libraryID, collectionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task AddShowLink(Show show, Library library, Collection collection)
|
||||||
|
{
|
||||||
|
if (show == null)
|
||||||
|
throw new ArgumentNullException(nameof(show));
|
||||||
|
return AddShowLink(show.ID, library?.ID, collection?.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Episode GetMovieEpisode(string movieSlug)
|
public Task<ICollection<Library>> SearchLibraries(string searchQuery)
|
||||||
{
|
{
|
||||||
return _database.Episodes.FirstOrDefault(x => x.Show.Slug == movieSlug);
|
return _libraries.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Genre GetGenre(string slug)
|
public Task<ICollection<Collection>> SearchCollections(string searchQuery)
|
||||||
{
|
{
|
||||||
return _database.Genres.FirstOrDefault(genre => genre.Slug == slug);
|
return _collections.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Studio GetStudio(string slug)
|
public Task<ICollection<Show>> SearchShows(string searchQuery)
|
||||||
{
|
{
|
||||||
return _database.Studios.FirstOrDefault(studio => studio.Slug == slug);
|
return _shows.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public People GetPeople(string slug)
|
public Task<ICollection<Season>> SearchSeasons(string searchQuery)
|
||||||
{
|
{
|
||||||
return _database.Peoples.FirstOrDefault(people => people.Slug == slug);
|
return _seasons.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProviderID GetProvider(string name)
|
public Task<ICollection<Episode>> SearchEpisodes(string searchQuery)
|
||||||
{
|
{
|
||||||
return _database.Providers.FirstOrDefault(x => x.Name == name);
|
return _episodes.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
public Task<ICollection<Genre>> SearchGenres(string searchQuery)
|
||||||
|
|
||||||
#region GetAll
|
|
||||||
public IEnumerable<Library> GetLibraries()
|
|
||||||
{
|
{
|
||||||
return _database.Libraries;
|
return _genres.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Collection> GetCollections()
|
public Task<ICollection<Studio>> SearchStudios(string searchQuery)
|
||||||
{
|
{
|
||||||
return _database.Collections;
|
return _studios.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Show> GetShows()
|
public Task<ICollection<People>> SearchPeople(string searchQuery)
|
||||||
{
|
{
|
||||||
return _database.Shows;
|
return _people.Search(searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Episode> GetEpisodes()
|
public Task RegisterLibrary(Library library)
|
||||||
{
|
{
|
||||||
return _database.Episodes;
|
return _libraries.Create(library);
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Genre> GetGenres()
|
|
||||||
{
|
|
||||||
return _database.Genres;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Studio> GetStudios()
|
|
||||||
{
|
|
||||||
return _database.Studios;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<People> GetPeoples()
|
public Task RegisterCollection(Collection collection)
|
||||||
{
|
{
|
||||||
return _database.Peoples;
|
return _collections.Create(collection);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Track> GetTracks()
|
public Task RegisterShow(Show show)
|
||||||
{
|
{
|
||||||
return _database.Tracks;
|
return _shows.Create(show);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
public Task RegisterSeason(Season season)
|
||||||
|
|
||||||
#region GetHelper
|
|
||||||
public IEnumerable<string> GetLibrariesPath()
|
|
||||||
{
|
{
|
||||||
IEnumerable<string> paths = new List<string>();
|
return _seasons.Create(season);
|
||||||
return Enumerable.Aggregate(_database.Libraries, paths, (current, lib) => current.Concat(lib.Paths));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Show GetShowByPath(string path)
|
|
||||||
{
|
|
||||||
return _database.Shows.FirstOrDefault(show => show.Path == path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Episode> GetEpisodes(string showSlug, long seasonNumber)
|
public Task RegisterEpisode(Episode episode)
|
||||||
{
|
{
|
||||||
return _database.Episodes.Where(x => x.Show.Slug == showSlug && x.SeasonNumber == seasonNumber);
|
return _episodes.Create(episode);
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Search
|
|
||||||
public IEnumerable<Collection> SearchCollections(string searchQuery)
|
|
||||||
{
|
|
||||||
return _database.Collections.Where(collection => EF.Functions.Like(collection.Name, $"%{searchQuery}%"))
|
|
||||||
.Take(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Show> SearchShows(string searchQuery)
|
|
||||||
{
|
|
||||||
return _database.Shows.FromSqlInterpolated($@"SELECT * FROM Shows WHERE Shows.Title LIKE {$"%{searchQuery}%"}
|
|
||||||
OR Shows.Aliases LIKE {$"%{searchQuery}%"}").Take(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Episode> SearchEpisodes(string searchQuery)
|
|
||||||
{
|
|
||||||
return _database.Episodes.Where(x => EF.Functions.Like(x.Title, $"%{searchQuery}%")).Take(20);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Genre> SearchGenres(string searchQuery)
|
public Task RegisterTrack(Track track)
|
||||||
{
|
{
|
||||||
return _database.Genres.Where(genre => EF.Functions.Like(genre.Name, $"%{searchQuery}%"))
|
return _tracks.Create(track);
|
||||||
.Take(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Studio> SearchStudios(string searchQuery)
|
|
||||||
{
|
|
||||||
return _database.Studios.Where(studio => EF.Functions.Like(studio.Name, $"%{searchQuery}%"))
|
|
||||||
.Take(20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<People> SearchPeople(string searchQuery)
|
|
||||||
{
|
|
||||||
return _database.Peoples.Where(people => EF.Functions.Like(people.Name, $"%{searchQuery}%"))
|
|
||||||
.OrderBy(x => x.ImgPrimary == null)
|
|
||||||
.ThenBy(x => x.Name)
|
|
||||||
.Take(20);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Register
|
|
||||||
public void Register(object obj)
|
|
||||||
{
|
|
||||||
if (obj == null)
|
|
||||||
return;
|
|
||||||
ValidateRootEntry(_database.Entry(obj), entry =>
|
|
||||||
{
|
|
||||||
if (entry.State != EntityState.Detached)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
entry.State = EntityState.Added;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RegisterShowLinks(Library library, Collection collection, Show show)
|
public Task RegisterGenre(Genre genre)
|
||||||
{
|
{
|
||||||
if (collection != null)
|
return _genres.Create(genre);
|
||||||
{
|
|
||||||
_database.LibraryLinks.AddIfNotExist(new LibraryLink {Library = library, Collection = collection},
|
|
||||||
x => x.Library == library && x.Collection == collection && x.ShowID == null);
|
|
||||||
_database.CollectionLinks.AddIfNotExist(new CollectionLink { Collection = collection, Show = show},
|
|
||||||
x => x.Collection == collection && x.Show == show);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_database.LibraryLinks.AddIfNotExist(new LibraryLink {Library = library, Show = show},
|
|
||||||
x => x.Library == library && x.Collection == null && x.Show == show);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task SaveChanges()
|
public Task RegisterStudio(Studio studio)
|
||||||
{
|
{
|
||||||
return SaveChanges(0);
|
return _studios.Create(studio);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task SaveChanges(int retryCount)
|
public Task RegisterPeople(People people)
|
||||||
{
|
{
|
||||||
ValidateChanges();
|
return _people.Create(people);
|
||||||
try
|
|
||||||
{
|
|
||||||
await _database.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
catch (DbUpdateException)
|
|
||||||
{
|
|
||||||
if (retryCount < MaxSaveRetry)
|
|
||||||
await SaveChanges(retryCount + 1);
|
|
||||||
else
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task Edit(object obj, bool resetOld)
|
|
||||||
{
|
|
||||||
_database.ChangeTracker.LazyLoadingEnabled = false;
|
|
||||||
_database.ChangeTracker.AutoDetectChangesEnabled = false;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
object existing = FindExisting(obj);
|
|
||||||
|
|
||||||
if (existing == null)
|
|
||||||
throw new ItemNotFound($"No existing object (of type {obj.GetType().Name}) found on the databse.");
|
|
||||||
|
|
||||||
if (resetOld)
|
|
||||||
Utility.Nullify(existing);
|
|
||||||
Utility.Merge(existing, obj);
|
|
||||||
|
|
||||||
ValidateRootEntry(_database.Entry(existing), entry => entry.State != EntityState.Added);
|
|
||||||
|
|
||||||
_database.ChangeTracker.DetectChanges();
|
|
||||||
await _database.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_database.ChangeTracker.LazyLoadingEnabled = true;
|
|
||||||
_database.ChangeTracker.AutoDetectChangesEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region ValidateValue
|
|
||||||
private void ValidateChanges()
|
|
||||||
{
|
|
||||||
_database.ChangeTracker.AutoDetectChangesEnabled = false;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
foreach (EntityEntry sourceEntry in _database.ChangeTracker.Entries())
|
|
||||||
{
|
|
||||||
if (sourceEntry.State != EntityState.Added && sourceEntry.State != EntityState.Modified)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
foreach (NavigationEntry navigation in sourceEntry.Navigations)
|
|
||||||
ValidateNavigation(navigation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_database.ChangeTracker.AutoDetectChangesEnabled = true;
|
|
||||||
_database.ChangeTracker.DetectChanges();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ValidateRootEntry(EntityEntry entry, Func<EntityEntry, bool> shouldRun)
|
|
||||||
{
|
|
||||||
if (!shouldRun.Invoke(entry))
|
|
||||||
return;
|
|
||||||
foreach (NavigationEntry navigation in entry.Navigations)
|
|
||||||
{
|
|
||||||
ValidateNavigation(navigation);
|
|
||||||
if (navigation.CurrentValue == null)
|
|
||||||
continue;
|
|
||||||
if (navigation.Metadata.IsCollection())
|
|
||||||
{
|
|
||||||
IEnumerable entities = (IEnumerable)navigation.CurrentValue;
|
|
||||||
foreach (object childEntry in entities)
|
|
||||||
ValidateRootEntry(_database.Entry(childEntry), shouldRun);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ValidateRootEntry(_database.Entry(navigation.CurrentValue), shouldRun);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ValidateNavigation(NavigationEntry navigation)
|
public Task EditLibrary(Library library, bool resetOld)
|
||||||
{
|
{
|
||||||
object oldValue = navigation.CurrentValue;
|
return _libraries.Edit(library, resetOld);
|
||||||
if (oldValue == null)
|
|
||||||
return;
|
|
||||||
object newValue = Validate(oldValue);
|
|
||||||
if (ReferenceEquals(oldValue, newValue))
|
|
||||||
return;
|
|
||||||
navigation.CurrentValue = newValue;
|
|
||||||
if (!navigation.Metadata.IsCollection())
|
|
||||||
_database.Entry(oldValue).State = EntityState.Detached;
|
|
||||||
}
|
|
||||||
|
|
||||||
private T Validate<T>(T obj) where T : class
|
|
||||||
{
|
|
||||||
switch (obj)
|
|
||||||
{
|
|
||||||
case null:
|
|
||||||
return null;
|
|
||||||
case IEnumerable<object> enumerable:
|
|
||||||
return (T)Utility.RunGenericMethod(
|
|
||||||
this,
|
|
||||||
"ValidateList",
|
|
||||||
Utility.GetEnumerableType(enumerable), new [] {obj});
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityState state = _database.Entry(obj).State;
|
|
||||||
if (state != EntityState.Added && state != EntityState.Detached)
|
|
||||||
return obj;
|
|
||||||
|
|
||||||
return (T)(FindExisting(obj) ?? obj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<T> ValidateList<T>(IEnumerable<T> list) where T : class
|
public Task EditCollection(Collection collection, bool resetOld)
|
||||||
{
|
{
|
||||||
return list.Select(x =>
|
return _collections.Edit(collection, resetOld);
|
||||||
{
|
|
||||||
T tmp = Validate(x);
|
|
||||||
if (tmp != x)
|
|
||||||
_database.Entry(x).State = EntityState.Detached;
|
|
||||||
return tmp ?? x;
|
|
||||||
})/*.GroupBy(GetSlug).Select(x => x.First()).Where(x => x != null)*/.ToList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private object FindExisting(object obj)
|
public Task EditShow(Show show, bool resetOld)
|
||||||
{
|
{
|
||||||
return obj switch
|
return _shows.Edit(show, resetOld);
|
||||||
{
|
|
||||||
Library library => GetLibrary(library.Slug),
|
|
||||||
Collection collection => GetCollection(collection.Slug),
|
|
||||||
Show show => GetShow(show.Slug),
|
|
||||||
Season season => GetSeason(season.Show.Slug, season.SeasonNumber),
|
|
||||||
Episode episode => GetEpisode(episode.Show.Slug, episode.SeasonNumber, episode.EpisodeNumber),
|
|
||||||
Studio studio => GetStudio(studio.Slug),
|
|
||||||
People people => GetPeople(people.Slug),
|
|
||||||
Genre genre => GetGenre(genre.Slug),
|
|
||||||
ProviderID provider => GetProvider(provider.Name),
|
|
||||||
_ => null
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<MetadataID> Validate(IEnumerable<MetadataID> ids)
|
public Task EditSeason(Season season, bool resetOld)
|
||||||
{
|
{
|
||||||
return ids?.Select(x =>
|
return _seasons.Edit(season, resetOld);
|
||||||
{
|
|
||||||
x.Provider = _database.Providers.FirstOrDefault(y => y.Name == x.Provider.Name) ?? x.Provider;
|
|
||||||
return x;
|
|
||||||
}).GroupBy(x => x.Provider.Name).Select(x => x.First()).ToList();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Remove
|
|
||||||
public void RemoveShow(Show show)
|
|
||||||
{
|
|
||||||
if (_database.Entry(show).State == EntityState.Detached)
|
|
||||||
_database.Shows.Attach(show);
|
|
||||||
_database.Shows.Remove(show);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveSeason(Season season)
|
public Task EditEpisode(Episode episode, bool resetOld)
|
||||||
{
|
{
|
||||||
if (_database.Entry(season).State == EntityState.Detached)
|
return _episodes.Edit(episode, resetOld);
|
||||||
_database.Seasons.Attach(season);
|
|
||||||
_database.Seasons.Remove(season);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveEpisode(Episode episode)
|
public Task EditTrack(Track track, bool resetOld)
|
||||||
{
|
{
|
||||||
if (_database.Entry(episode).State == EntityState.Detached)
|
return _tracks.Edit(track, resetOld);
|
||||||
_database.Episodes.Attach(episode);
|
}
|
||||||
_database.Episodes.Remove(episode);
|
|
||||||
|
public Task EditGenre(Genre genre, bool resetOld)
|
||||||
|
{
|
||||||
|
return _genres.Edit(genre, resetOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task EditStudio(Studio studio, bool resetOld)
|
||||||
|
{
|
||||||
|
return _studios.Edit(studio, resetOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task EditPeople(People people, bool resetOld)
|
||||||
|
{
|
||||||
|
return _people.Edit(people, resetOld);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DelteLibrary(Library library)
|
||||||
|
{
|
||||||
|
return _libraries.Delete(library);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteCollection(Collection collection)
|
||||||
|
{
|
||||||
|
return _collections.Delete(collection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteShow(Show show)
|
||||||
|
{
|
||||||
|
return _shows.Delete(show);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteSeason(Season season)
|
||||||
|
{
|
||||||
|
return _seasons.Delete(season);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteEpisode(Episode episode)
|
||||||
|
{
|
||||||
|
return _episodes.Delete(episode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteTrack(Track track)
|
||||||
|
{
|
||||||
|
return _tracks.Delete(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteGenre(Genre genre)
|
||||||
|
{
|
||||||
|
return _genres.Delete(genre);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeleteStudio(Studio studio)
|
||||||
|
{
|
||||||
|
return _studios.Delete(studio);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task DeletePeople(People people)
|
||||||
|
{
|
||||||
|
return _people.Delete(people);
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,13 +113,14 @@ namespace Kyoo.Controllers
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Season> GetSeason(Show show, long seasonNumber, Library library)
|
public async Task<Season> GetSeason(Show show, int seasonNumber, Library library)
|
||||||
{
|
{
|
||||||
Season season = await GetMetadata(
|
Season season = await GetMetadata(
|
||||||
provider => provider.GetSeason(show, seasonNumber),
|
provider => provider.GetSeason(show, seasonNumber),
|
||||||
library,
|
library,
|
||||||
$"the season {seasonNumber} of {show.Title}");
|
$"the season {seasonNumber} of {show.Title}");
|
||||||
season.Show = show;
|
season.Show = show;
|
||||||
|
season.ShowID = show.ID;
|
||||||
season.SeasonNumber = season.SeasonNumber == -1 ? seasonNumber : season.SeasonNumber;
|
season.SeasonNumber = season.SeasonNumber == -1 ? seasonNumber : season.SeasonNumber;
|
||||||
season.Title ??= $"Season {season.SeasonNumber}";
|
season.Title ??= $"Season {season.SeasonNumber}";
|
||||||
return season;
|
return season;
|
||||||
@ -127,9 +128,9 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
public async Task<Episode> GetEpisode(Show show,
|
public async Task<Episode> GetEpisode(Show show,
|
||||||
string episodePath,
|
string episodePath,
|
||||||
long seasonNumber,
|
int seasonNumber,
|
||||||
long episodeNumber,
|
int episodeNumber,
|
||||||
long absoluteNumber,
|
int absoluteNumber,
|
||||||
Library library)
|
Library library)
|
||||||
{
|
{
|
||||||
Episode episode = await GetMetadata(
|
Episode episode = await GetMetadata(
|
||||||
@ -137,6 +138,7 @@ namespace Kyoo.Controllers
|
|||||||
library,
|
library,
|
||||||
"an episode");
|
"an episode");
|
||||||
episode.Show = show;
|
episode.Show = show;
|
||||||
|
episode.ShowID = show.ID;
|
||||||
episode.Path = episodePath;
|
episode.Path = episodePath;
|
||||||
episode.SeasonNumber = episode.SeasonNumber != -1 ? episode.SeasonNumber : seasonNumber;
|
episode.SeasonNumber = episode.SeasonNumber != -1 ? episode.SeasonNumber : seasonNumber;
|
||||||
episode.EpisodeNumber = episode.EpisodeNumber != -1 ? episode.EpisodeNumber : episodeNumber;
|
episode.EpisodeNumber = episode.EpisodeNumber != -1 ? episode.EpisodeNumber : episodeNumber;
|
||||||
@ -155,6 +157,7 @@ namespace Kyoo.Controllers
|
|||||||
.Select(x =>
|
.Select(x =>
|
||||||
{
|
{
|
||||||
x.Show = show;
|
x.Show = show;
|
||||||
|
x.ShowID = show.ID;
|
||||||
return x;
|
return x;
|
||||||
}).ToList();
|
}).ToList();
|
||||||
}
|
}
|
||||||
|
88
Kyoo/Controllers/Repositories/CollectionRepository.cs
Normal file
88
Kyoo/Controllers/Repositories/CollectionRepository.cs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class CollectionRepository : ICollectionRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
|
||||||
|
|
||||||
|
public CollectionRepository(DatabaseContext database)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Collection> Get(int id)
|
||||||
|
{
|
||||||
|
return _database.Collections.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Collection> Get(string slug)
|
||||||
|
{
|
||||||
|
return _database.Collections.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Collection>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Collections
|
||||||
|
.Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Collection>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Collections.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Collection obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await _database.Collections.AddAsync(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(Collection obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
Collection old = await Get(obj.Slug);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Collection edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Collection old = await Get(edited.Slug);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No collection found with the slug {edited.Slug}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Collection obj)
|
||||||
|
{
|
||||||
|
_database.Collections.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
147
Kyoo/Controllers/Repositories/EpisodeRepository.cs
Normal file
147
Kyoo/Controllers/Repositories/EpisodeRepository.cs
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class EpisodeRepository : IEpisodeRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public EpisodeRepository(DatabaseContext database, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Episode> Get(int id)
|
||||||
|
{
|
||||||
|
return await _database.Episodes.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Episode> Get(string slug)
|
||||||
|
{
|
||||||
|
int sIndex = slug.IndexOf("-s", StringComparison.Ordinal);
|
||||||
|
int eIndex = slug.IndexOf("-e", StringComparison.Ordinal);
|
||||||
|
if (sIndex == -1 || eIndex == -1 || eIndex < sIndex)
|
||||||
|
throw new InvalidOperationException("Invalid episode slug. Format: {showSlug}-s{seasonNumber}-e{episodeNumber}");
|
||||||
|
string showSlug = slug.Substring(0, sIndex);
|
||||||
|
if (!int.TryParse(slug.Substring(sIndex + 2), out int seasonNumber))
|
||||||
|
throw new InvalidOperationException("Invalid episode slug. Format: {showSlug}-s{seasonNumber}-e{episodeNumber}");
|
||||||
|
if (!int.TryParse(slug.Substring(eIndex + 2), out int episodeNumber))
|
||||||
|
throw new InvalidOperationException("Invalid episode slug. Format: {showSlug}-s{seasonNumber}-e{episodeNumber}");
|
||||||
|
return Get(showSlug, seasonNumber, episodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Episode> Get(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
|
{
|
||||||
|
return await _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
||||||
|
&& x.SeasonNumber == seasonNumber
|
||||||
|
&& x.EpisodeNumber == episodeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Episode>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Episodes
|
||||||
|
.Where(x => EF.Functions.Like(x.Title, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Episode>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Episodes.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Episode obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await Validate(obj);
|
||||||
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
|
if (obj.ExternalIDs != null)
|
||||||
|
foreach (MetadataID entry in obj.ExternalIDs)
|
||||||
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(Episode obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
Episode old = await Get(obj.Slug);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Episode edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Episode old = await Get(edited.Slug);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No episode found with the slug {edited.Slug}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
|
||||||
|
await Validate(old);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Validate(Episode obj)
|
||||||
|
{
|
||||||
|
if (obj.ShowID <= 0)
|
||||||
|
throw new InvalidOperationException($"Can't store an episode not related to any show (showID: {obj.ShowID}).");
|
||||||
|
|
||||||
|
if (obj.ExternalIDs != null)
|
||||||
|
{
|
||||||
|
obj.ExternalIDs = (await Task.WhenAll(obj.ExternalIDs.Select(async x =>
|
||||||
|
{
|
||||||
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
|
IProviderRepository providers = serviceScope.ServiceProvider.GetService<IProviderRepository>();
|
||||||
|
|
||||||
|
x.ProviderID = await providers.CreateIfNotExists(x.Provider);
|
||||||
|
return x;
|
||||||
|
}))).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Episode obj)
|
||||||
|
{
|
||||||
|
_database.Episodes.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Episode>> GetEpisodes(int showID, int seasonNumber)
|
||||||
|
{
|
||||||
|
return await _database.Episodes.Where(x => x.ShowID == showID
|
||||||
|
&& x.SeasonNumber == seasonNumber).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Episode>> GetEpisodes(string showSlug, int seasonNumber)
|
||||||
|
{
|
||||||
|
return await _database.Episodes.Where(x => x.Show.Slug == showSlug
|
||||||
|
&& x.SeasonNumber == seasonNumber).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Episode>> GetEpisodes(int seasonID)
|
||||||
|
{
|
||||||
|
return await _database.Episodes.Where(x => x.SeasonID == seasonID).ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
Kyoo/Controllers/Repositories/GenreRepository.cs
Normal file
87
Kyoo/Controllers/Repositories/GenreRepository.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class GenreRepository : IGenreRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
|
||||||
|
|
||||||
|
public GenreRepository(DatabaseContext database)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Genre> Get(int id)
|
||||||
|
{
|
||||||
|
return await _database.Genres.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Genre> Get(string slug)
|
||||||
|
{
|
||||||
|
return await _database.Genres.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Genre>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Genres
|
||||||
|
.Where(genre => EF.Functions.Like(genre.Name, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Genre>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Genres.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Genre obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await _database.Genres.AddAsync(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(Genre obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
Genre old = await Get(obj.Slug);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Genre edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Genre old = await Get(edited.Slug);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No genre found with the slug {edited.Slug}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Genre obj)
|
||||||
|
{
|
||||||
|
_database.Genres.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
107
Kyoo/Controllers/Repositories/LibraryRepository.cs
Normal file
107
Kyoo/Controllers/Repositories/LibraryRepository.cs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class LibraryRepository : ILibraryRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public LibraryRepository(DatabaseContext database, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Library> Get(int id)
|
||||||
|
{
|
||||||
|
return _database.Libraries.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Library> Get(string slug)
|
||||||
|
{
|
||||||
|
return _database.Libraries.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Library>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Libraries
|
||||||
|
.Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Library>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Libraries.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Library obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await Validate(obj);
|
||||||
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
|
if (obj.ProviderLinks != null)
|
||||||
|
foreach (ProviderLink entry in obj.ProviderLinks)
|
||||||
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(Library obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
Library old = await Get(obj.Name);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Library edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Library old = await Get(edited.Name);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No library found with the name {edited.Name}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
await Validate(old);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Validate(Library obj)
|
||||||
|
{
|
||||||
|
obj.ProviderLinks = (await Task.WhenAll(obj.ProviderLinks.Select(async x =>
|
||||||
|
{
|
||||||
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
|
IProviderRepository providers = serviceScope.ServiceProvider.GetService<IProviderRepository>();
|
||||||
|
|
||||||
|
x.ProviderID = await providers.CreateIfNotExists(x.Provider);
|
||||||
|
return x;
|
||||||
|
}))).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Library obj)
|
||||||
|
{
|
||||||
|
_database.Libraries.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
106
Kyoo/Controllers/Repositories/PeopleRepository.cs
Normal file
106
Kyoo/Controllers/Repositories/PeopleRepository.cs
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class PeopleRepository : IPeopleRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
public PeopleRepository(DatabaseContext database, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<People> Get(int id)
|
||||||
|
{
|
||||||
|
return _database.Peoples.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<People> Get(string slug)
|
||||||
|
{
|
||||||
|
return _database.Peoples.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<People>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Peoples
|
||||||
|
.Where(people => EF.Functions.Like(people.Name, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<People>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Peoples.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(People obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await Validate(obj);
|
||||||
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
|
if (obj.ExternalIDs != null)
|
||||||
|
foreach (MetadataID entry in obj.ExternalIDs)
|
||||||
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(People obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
People old = await Get(obj.Slug);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(People edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
People old = await Get(edited.Slug);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No people found with the slug {edited.Slug}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
await Validate(old);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Validate(People obj)
|
||||||
|
{
|
||||||
|
obj.ExternalIDs = (await Task.WhenAll(obj.ExternalIDs.Select(async x =>
|
||||||
|
{
|
||||||
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
|
IProviderRepository providers = serviceScope.ServiceProvider.GetService<IProviderRepository>();
|
||||||
|
|
||||||
|
x.ProviderID = await providers.CreateIfNotExists(x.Provider);
|
||||||
|
return x;
|
||||||
|
}))).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(People obj)
|
||||||
|
{
|
||||||
|
_database.Peoples.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
Kyoo/Controllers/Repositories/ProviderRepository.cs
Normal file
87
Kyoo/Controllers/Repositories/ProviderRepository.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class ProviderRepository : IProviderRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
|
||||||
|
|
||||||
|
public ProviderRepository(DatabaseContext database)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ProviderID> Get(int id)
|
||||||
|
{
|
||||||
|
return await _database.Providers.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ProviderID> Get(string slug)
|
||||||
|
{
|
||||||
|
return await _database.Providers.FirstOrDefaultAsync(x => x.Name == slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<ProviderID>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Providers
|
||||||
|
.Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<ProviderID>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Providers.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(ProviderID obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await _database.Providers.AddAsync(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(ProviderID obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
ProviderID old = await Get(obj.Name);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(ProviderID edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
ProviderID old = await Get(edited.Name);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No provider found with the name {edited.Name}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(ProviderID obj)
|
||||||
|
{
|
||||||
|
_database.Providers.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
136
Kyoo/Controllers/Repositories/SeasonRepository.cs
Normal file
136
Kyoo/Controllers/Repositories/SeasonRepository.cs
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class SeasonRepository : ISeasonRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
|
||||||
|
|
||||||
|
public SeasonRepository(DatabaseContext database, IServiceProvider serviceProvider)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Season> Get(int id)
|
||||||
|
{
|
||||||
|
return await _database.Seasons.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Season> Get(string slug)
|
||||||
|
{
|
||||||
|
int index = slug.IndexOf("-s", StringComparison.Ordinal);
|
||||||
|
if (index == -1)
|
||||||
|
throw new InvalidOperationException("Invalid season slug. Format: {showSlug}-s{seasonNumber}");
|
||||||
|
string showSlug = slug.Substring(0, index);
|
||||||
|
if (!int.TryParse(slug.Substring(index + 2), out int seasonNumber))
|
||||||
|
throw new InvalidOperationException("Invalid season slug. Format: {showSlug}-s{seasonNumber}");
|
||||||
|
return Get(showSlug, seasonNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Season> Get(string showSlug, int seasonNumber)
|
||||||
|
{
|
||||||
|
return await _database.Seasons.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
||||||
|
&& x.SeasonNumber == seasonNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Season>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Seasons
|
||||||
|
.Where(x => EF.Functions.Like(x.Title, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Season>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Seasons.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Season obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await Validate(obj);
|
||||||
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
|
if (obj.ExternalIDs != null)
|
||||||
|
foreach (MetadataID entry in obj.ExternalIDs)
|
||||||
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(Season obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
Season old = await Get(obj.Slug);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Season edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Season old = await Get(edited.Slug);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No season found with the slug {edited.Slug}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
|
||||||
|
await Validate(old);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Validate(Season obj)
|
||||||
|
{
|
||||||
|
if (obj.ShowID <= 0)
|
||||||
|
throw new InvalidOperationException($"Can't store a season not related to any show (showID: {obj.ShowID}).");
|
||||||
|
|
||||||
|
if (obj.ExternalIDs != null)
|
||||||
|
{
|
||||||
|
obj.ExternalIDs = (await Task.WhenAll(obj.ExternalIDs.Select(async x =>
|
||||||
|
{
|
||||||
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
|
IProviderRepository providers = serviceScope.ServiceProvider.GetService<IProviderRepository>();
|
||||||
|
|
||||||
|
x.ProviderID = await providers.CreateIfNotExists(x.Provider);
|
||||||
|
return x;
|
||||||
|
}))).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Season obj)
|
||||||
|
{
|
||||||
|
_database.Seasons.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Season>> GetSeasons(int showID)
|
||||||
|
{
|
||||||
|
return await _database.Seasons.Where(x => x.ShowID == showID).ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Season>> GetSeasons(string showSlug)
|
||||||
|
{
|
||||||
|
return await _database.Seasons.Where(x => x.Show.Slug == showSlug).ToListAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
175
Kyoo/Controllers/Repositories/ShowRepository.cs
Normal file
175
Kyoo/Controllers/Repositories/ShowRepository.cs
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class ShowRepository : IShowRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
private readonly IServiceProvider _serviceProvider;
|
||||||
|
private readonly IStudioRepository _studios;
|
||||||
|
|
||||||
|
public ShowRepository(DatabaseContext database,
|
||||||
|
IServiceProvider serviceProvider,
|
||||||
|
IStudioRepository studios)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
_serviceProvider = serviceProvider;
|
||||||
|
_studios = studios;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Show> Get(int id)
|
||||||
|
{
|
||||||
|
return await _database.Shows.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Show> Get(string slug)
|
||||||
|
{
|
||||||
|
return await _database.Shows.FirstOrDefaultAsync(x => x.Slug == slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Show> GetByPath(string path)
|
||||||
|
{
|
||||||
|
return await _database.Shows.FirstOrDefaultAsync(x => x.Path == path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Show>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Shows
|
||||||
|
.FromSqlInterpolated($@"SELECT * FROM Shows WHERE Shows.Title LIKE {$"%{query}%"}
|
||||||
|
OR Shows.Aliases LIKE {$"%{query}%"}")
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Show>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Shows.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Show obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await Validate(obj);
|
||||||
|
_database.Entry(obj).State = EntityState.Added;
|
||||||
|
if (obj.GenreLinks != null)
|
||||||
|
foreach (GenreLink entry in obj.GenreLinks)
|
||||||
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
|
if (obj.People != null)
|
||||||
|
foreach (PeopleLink entry in obj.People)
|
||||||
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
|
if (obj.ExternalIDs != null)
|
||||||
|
foreach (MetadataID entry in obj.ExternalIDs)
|
||||||
|
_database.Entry(entry).State = EntityState.Added;
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(Show obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
Show old = await Get(obj.Slug);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Show edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Show old = await Get(edited.Slug);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No show found with the slug {edited.Slug}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
await Validate(old);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task Validate(Show obj)
|
||||||
|
{
|
||||||
|
if (obj.Studio != null)
|
||||||
|
obj.StudioID = await _studios.CreateIfNotExists(obj.Studio);
|
||||||
|
|
||||||
|
if (obj.GenreLinks != null)
|
||||||
|
{
|
||||||
|
obj.GenreLinks = (await Task.WhenAll(obj.GenreLinks.Select(async x =>
|
||||||
|
{
|
||||||
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
|
IGenreRepository genres = serviceScope.ServiceProvider.GetService<IGenreRepository>();
|
||||||
|
|
||||||
|
x.GenreID = await genres.CreateIfNotExists(x.Genre);
|
||||||
|
return x;
|
||||||
|
}))).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.People != null)
|
||||||
|
{
|
||||||
|
obj.People = (await Task.WhenAll(obj.People.Select(async x =>
|
||||||
|
{
|
||||||
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
|
IPeopleRepository people = serviceScope.ServiceProvider.GetService<IPeopleRepository>();
|
||||||
|
|
||||||
|
x.PeopleID = await people.CreateIfNotExists(x.People);
|
||||||
|
return x;
|
||||||
|
}))).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.ExternalIDs != null)
|
||||||
|
{
|
||||||
|
obj.ExternalIDs = (await Task.WhenAll(obj.ExternalIDs.Select(async x =>
|
||||||
|
{
|
||||||
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
|
IProviderRepository providers = serviceScope.ServiceProvider.GetService<IProviderRepository>();
|
||||||
|
|
||||||
|
x.ProviderID = await providers.CreateIfNotExists(x.Provider);
|
||||||
|
return x;
|
||||||
|
}))).ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Show show)
|
||||||
|
{
|
||||||
|
_database.Shows.Remove(show);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task AddShowLink(int showID, int? libraryID, int? collectionID)
|
||||||
|
{
|
||||||
|
if (collectionID != null)
|
||||||
|
{
|
||||||
|
_database.CollectionLinks.AddIfNotExist(new CollectionLink { CollectionID = collectionID, ShowID = showID},
|
||||||
|
x => x.CollectionID == collectionID && x.ShowID == showID);
|
||||||
|
}
|
||||||
|
if (libraryID != null)
|
||||||
|
{
|
||||||
|
_database.LibraryLinks.AddIfNotExist(new LibraryLink {LibraryID = libraryID.Value, ShowID = showID},
|
||||||
|
x => x.LibraryID == libraryID.Value && x.CollectionID == null && x.ShowID == showID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (libraryID != null && collectionID != null)
|
||||||
|
{
|
||||||
|
_database.LibraryLinks.AddIfNotExist(
|
||||||
|
new LibraryLink {LibraryID = libraryID.Value, CollectionID = collectionID.Value},
|
||||||
|
x => x.LibraryID == libraryID && x.CollectionID == collectionID && x.ShowID == null);
|
||||||
|
}
|
||||||
|
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
Kyoo/Controllers/Repositories/StudioRepository.cs
Normal file
87
Kyoo/Controllers/Repositories/StudioRepository.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class StudioRepository : IStudioRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
|
||||||
|
|
||||||
|
public StudioRepository(DatabaseContext database)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Studio> Get(int id)
|
||||||
|
{
|
||||||
|
return await _database.Studios.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Studio> Get(string slug)
|
||||||
|
{
|
||||||
|
return await _database.Studios.FirstOrDefaultAsync(x => x.Name == slug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Studio>> Search(string query)
|
||||||
|
{
|
||||||
|
return await _database.Studios
|
||||||
|
.Where(x => EF.Functions.Like(x.Name, $"%{query}%"))
|
||||||
|
.Take(20)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Studio>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Studios.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Studio obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
await _database.Studios.AddAsync(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> CreateIfNotExists(Studio obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
Studio old = await Get(obj.Name);
|
||||||
|
if (old != null)
|
||||||
|
return old.ID;
|
||||||
|
return await Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Studio edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Studio old = await Get(edited.Name);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No studio found with the name {edited.Name}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Studio obj)
|
||||||
|
{
|
||||||
|
_database.Studios.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
Kyoo/Controllers/Repositories/TrackRepository.cs
Normal file
88
Kyoo/Controllers/Repositories/TrackRepository.cs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Models;
|
||||||
|
using Kyoo.Models.Exceptions;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace Kyoo.Controllers
|
||||||
|
{
|
||||||
|
public class TrackRepository : ITrackRepository
|
||||||
|
{
|
||||||
|
private readonly DatabaseContext _database;
|
||||||
|
|
||||||
|
|
||||||
|
public TrackRepository(DatabaseContext database)
|
||||||
|
{
|
||||||
|
_database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Track> Get(int id)
|
||||||
|
{
|
||||||
|
return await _database.Tracks.FirstOrDefaultAsync(x => x.ID == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Track> Get(string slug)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Tracks do not support the get by slug method.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<Track> Get(int episodeID, string languageTag, bool isForced)
|
||||||
|
{
|
||||||
|
return _database.Tracks.FirstOrDefaultAsync(x => x.EpisodeID == episodeID
|
||||||
|
&& x.Language == languageTag
|
||||||
|
&& x.IsForced == isForced);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<ICollection<Track>> Search(string query)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Tracks do not support the search method.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<ICollection<Track>> GetAll()
|
||||||
|
{
|
||||||
|
return await _database.Tracks.ToListAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<int> Create(Track obj)
|
||||||
|
{
|
||||||
|
if (obj == null)
|
||||||
|
throw new ArgumentNullException(nameof(obj));
|
||||||
|
|
||||||
|
if (obj.EpisodeID <= 0)
|
||||||
|
throw new InvalidOperationException($"Can't store a track not related to any episode (episodeID: {obj.EpisodeID}).");
|
||||||
|
|
||||||
|
obj.Episode = null;
|
||||||
|
await _database.Tracks.AddAsync(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
return obj.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task<int> CreateIfNotExists(Track obj)
|
||||||
|
{
|
||||||
|
return Create(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Edit(Track edited, bool resetOld)
|
||||||
|
{
|
||||||
|
if (edited == null)
|
||||||
|
throw new ArgumentNullException(nameof(edited));
|
||||||
|
|
||||||
|
Track old = await Get(edited.ID);
|
||||||
|
|
||||||
|
if (old == null)
|
||||||
|
throw new ItemNotFound($"No track found with the ID {edited.ID}.");
|
||||||
|
|
||||||
|
if (resetOld)
|
||||||
|
Utility.Nullify(old);
|
||||||
|
Utility.Merge(old, edited);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task Delete(Track obj)
|
||||||
|
{
|
||||||
|
_database.Tracks.Remove(obj);
|
||||||
|
await _database.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,7 +10,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
|||||||
namespace Kyoo.Models.DatabaseMigrations.Internal
|
namespace Kyoo.Models.DatabaseMigrations.Internal
|
||||||
{
|
{
|
||||||
[DbContext(typeof(DatabaseContext))]
|
[DbContext(typeof(DatabaseContext))]
|
||||||
[Migration("20200526235513_Initial")]
|
[Migration("20200607010830_Initial")]
|
||||||
partial class Initial
|
partial class Initial
|
||||||
{
|
{
|
||||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||||
@ -23,9 +23,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Collection", b =>
|
modelBuilder.Entity("Kyoo.Models.Collection", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
@ -53,16 +53,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
|
modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long?>("CollectionID")
|
b.Property<int?>("CollectionID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -75,16 +75,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Episode", b =>
|
modelBuilder.Entity("Kyoo.Models.Episode", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long>("AbsoluteNumber")
|
b.Property<int>("AbsoluteNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("EpisodeNumber")
|
b.Property<int>("EpisodeNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -98,17 +98,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<DateTime?>("ReleaseDate")
|
b.Property<DateTime?>("ReleaseDate")
|
||||||
.HasColumnType("timestamp without time zone");
|
.HasColumnType("timestamp without time zone");
|
||||||
|
|
||||||
b.Property<long>("Runtime")
|
b.Property<int>("Runtime")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("SeasonID")
|
b.Property<int?>("SeasonID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("SeasonNumber")
|
b.Property<int>("SeasonNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -124,9 +124,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Genre", b =>
|
modelBuilder.Entity("Kyoo.Models.Genre", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -145,11 +145,11 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
|
modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("GenreID")
|
b.Property<int>("GenreID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ShowID", "GenreID");
|
b.HasKey("ShowID", "GenreID");
|
||||||
|
|
||||||
@ -160,9 +160,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Library", b =>
|
modelBuilder.Entity("Kyoo.Models.Library", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -184,19 +184,19 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
|
modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long?>("CollectionID")
|
b.Property<int?>("CollectionID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("LibraryID")
|
b.Property<int>("LibraryID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("ShowID")
|
b.Property<int?>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -211,31 +211,31 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.MetadataID", b =>
|
modelBuilder.Entity("Kyoo.Models.MetadataID", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("DataID")
|
b.Property<string>("DataID")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("EpisodeID")
|
b.Property<int?>("EpisodeID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Link")
|
b.Property<string>("Link")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("PeopleID")
|
b.Property<int?>("PeopleID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ProviderID")
|
b.Property<int>("ProviderID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("SeasonID")
|
b.Property<int?>("SeasonID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("ShowID")
|
b.Property<int?>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -254,9 +254,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.People", b =>
|
modelBuilder.Entity("Kyoo.Models.People", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
@ -278,19 +278,19 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
|
modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long>("PeopleID")
|
b.Property<int>("PeopleID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Role")
|
b.Property<string>("Role")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Type")
|
b.Property<string>("Type")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -306,9 +306,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
|
modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Logo")
|
b.Property<string>("Logo")
|
||||||
@ -327,16 +327,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.ProviderLink", b =>
|
modelBuilder.Entity("Kyoo.Models.ProviderLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long?>("LibraryID")
|
b.Property<int?>("LibraryID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ProviderID")
|
b.Property<int>("ProviderID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -349,9 +349,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Season", b =>
|
modelBuilder.Entity("Kyoo.Models.Season", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
@ -360,17 +360,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<string>("Overview")
|
b.Property<string>("Overview")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long>("SeasonNumber")
|
b.Property<int>("SeasonNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("Year")
|
b.Property<int?>("Year")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -381,9 +381,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Show", b =>
|
modelBuilder.Entity("Kyoo.Models.Show", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Aliases")
|
b.Property<string>("Aliases")
|
||||||
@ -392,8 +392,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<string>("Backdrop")
|
b.Property<string>("Backdrop")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("EndYear")
|
b.Property<int?>("EndYear")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<bool>("IsMovie")
|
b.Property<bool>("IsMovie")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
@ -413,14 +413,14 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("StartYear")
|
b.Property<int?>("StartYear")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<int?>("Status")
|
b.Property<int?>("Status")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("StudioID")
|
b.Property<int?>("StudioID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -440,9 +440,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Studio", b =>
|
modelBuilder.Entity("Kyoo.Models.Studio", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -461,16 +461,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Track", b =>
|
modelBuilder.Entity("Kyoo.Models.Track", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Codec")
|
b.Property<string>("Codec")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long>("EpisodeID")
|
b.Property<int>("EpisodeID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<bool>("IsDefault")
|
b.Property<bool>("IsDefault")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
@ -12,7 +12,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Collections",
|
name: "Collections",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.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),
|
||||||
@ -29,7 +29,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Genres",
|
name: "Genres",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.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)
|
||||||
@ -43,7 +43,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Libraries",
|
name: "Libraries",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.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),
|
||||||
@ -58,7 +58,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Peoples",
|
name: "Peoples",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.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),
|
||||||
@ -73,7 +73,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Providers",
|
name: "Providers",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
Name = table.Column<string>(nullable: true),
|
Name = table.Column<string>(nullable: true),
|
||||||
Logo = table.Column<string>(nullable: true)
|
Logo = table.Column<string>(nullable: true)
|
||||||
@ -87,7 +87,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Studios",
|
name: "Studios",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.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)
|
||||||
@ -101,10 +101,10 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "ProviderLinks",
|
name: "ProviderLinks",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
ProviderID = table.Column<long>(nullable: false),
|
ProviderID = table.Column<int>(nullable: false),
|
||||||
LibraryID = table.Column<long>(nullable: true)
|
LibraryID = table.Column<int>(nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@ -127,7 +127,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Shows",
|
name: "Shows",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.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),
|
||||||
@ -136,13 +136,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
Overview = table.Column<string>(nullable: true),
|
Overview = table.Column<string>(nullable: true),
|
||||||
Status = table.Column<int>(nullable: true),
|
Status = table.Column<int>(nullable: true),
|
||||||
TrailerUrl = table.Column<string>(nullable: true),
|
TrailerUrl = table.Column<string>(nullable: true),
|
||||||
StartYear = table.Column<long>(nullable: true),
|
StartYear = table.Column<int>(nullable: true),
|
||||||
EndYear = table.Column<long>(nullable: true),
|
EndYear = table.Column<int>(nullable: true),
|
||||||
Poster = table.Column<string>(nullable: true),
|
Poster = table.Column<string>(nullable: true),
|
||||||
Logo = table.Column<string>(nullable: true),
|
Logo = table.Column<string>(nullable: true),
|
||||||
Backdrop = table.Column<string>(nullable: true),
|
Backdrop = table.Column<string>(nullable: true),
|
||||||
IsMovie = table.Column<bool>(nullable: false),
|
IsMovie = table.Column<bool>(nullable: false),
|
||||||
StudioID = table.Column<long>(nullable: true)
|
StudioID = table.Column<int>(nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@ -159,10 +159,10 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "CollectionLinks",
|
name: "CollectionLinks",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
CollectionID = table.Column<long>(nullable: true),
|
CollectionID = table.Column<int>(nullable: true),
|
||||||
ShowID = table.Column<long>(nullable: false)
|
ShowID = table.Column<int>(nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@ -185,8 +185,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "GenreLinks",
|
name: "GenreLinks",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ShowID = table.Column<long>(nullable: false),
|
ShowID = table.Column<int>(nullable: false),
|
||||||
GenreID = table.Column<long>(nullable: false)
|
GenreID = table.Column<int>(nullable: false)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@ -209,11 +209,11 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "LibraryLinks",
|
name: "LibraryLinks",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
LibraryID = table.Column<long>(nullable: false),
|
LibraryID = table.Column<int>(nullable: false),
|
||||||
ShowID = table.Column<long>(nullable: true),
|
ShowID = table.Column<int>(nullable: true),
|
||||||
CollectionID = table.Column<long>(nullable: true)
|
CollectionID = table.Column<int>(nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
{
|
{
|
||||||
@ -242,10 +242,10 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "PeopleLinks",
|
name: "PeopleLinks",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
PeopleID = table.Column<long>(nullable: false),
|
PeopleID = table.Column<int>(nullable: false),
|
||||||
ShowID = table.Column<long>(nullable: false),
|
ShowID = table.Column<int>(nullable: false),
|
||||||
Role = table.Column<string>(nullable: true),
|
Role = table.Column<string>(nullable: true),
|
||||||
Type = table.Column<string>(nullable: true)
|
Type = table.Column<string>(nullable: true)
|
||||||
},
|
},
|
||||||
@ -270,13 +270,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Seasons",
|
name: "Seasons",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
ShowID = table.Column<long>(nullable: false),
|
ShowID = table.Column<int>(nullable: false),
|
||||||
SeasonNumber = table.Column<long>(nullable: false),
|
SeasonNumber = table.Column<int>(nullable: false),
|
||||||
Title = table.Column<string>(nullable: true),
|
Title = table.Column<string>(nullable: true),
|
||||||
Overview = table.Column<string>(nullable: true),
|
Overview = table.Column<string>(nullable: true),
|
||||||
Year = table.Column<long>(nullable: true),
|
Year = table.Column<int>(nullable: true),
|
||||||
ImgPrimary = table.Column<string>(nullable: true)
|
ImgPrimary = table.Column<string>(nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
@ -294,18 +294,18 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Episodes",
|
name: "Episodes",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
ShowID = table.Column<long>(nullable: false),
|
ShowID = table.Column<int>(nullable: false),
|
||||||
SeasonID = table.Column<long>(nullable: true),
|
SeasonID = table.Column<int>(nullable: true),
|
||||||
SeasonNumber = table.Column<long>(nullable: false),
|
SeasonNumber = table.Column<int>(nullable: false),
|
||||||
EpisodeNumber = table.Column<long>(nullable: false),
|
EpisodeNumber = table.Column<int>(nullable: false),
|
||||||
AbsoluteNumber = table.Column<long>(nullable: false),
|
AbsoluteNumber = table.Column<int>(nullable: false),
|
||||||
Path = table.Column<string>(nullable: true),
|
Path = table.Column<string>(nullable: true),
|
||||||
Title = table.Column<string>(nullable: true),
|
Title = table.Column<string>(nullable: true),
|
||||||
Overview = table.Column<string>(nullable: true),
|
Overview = table.Column<string>(nullable: true),
|
||||||
ReleaseDate = table.Column<DateTime>(nullable: true),
|
ReleaseDate = table.Column<DateTime>(nullable: true),
|
||||||
Runtime = table.Column<long>(nullable: false),
|
Runtime = table.Column<int>(nullable: false),
|
||||||
ImgPrimary = table.Column<string>(nullable: true)
|
ImgPrimary = table.Column<string>(nullable: true)
|
||||||
},
|
},
|
||||||
constraints: table =>
|
constraints: table =>
|
||||||
@ -329,13 +329,13 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "MetadataIds",
|
name: "MetadataIds",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
ProviderID = table.Column<long>(nullable: false),
|
ProviderID = table.Column<int>(nullable: false),
|
||||||
ShowID = table.Column<long>(nullable: true),
|
ShowID = table.Column<int>(nullable: true),
|
||||||
EpisodeID = table.Column<long>(nullable: true),
|
EpisodeID = table.Column<int>(nullable: true),
|
||||||
SeasonID = table.Column<long>(nullable: true),
|
SeasonID = table.Column<int>(nullable: true),
|
||||||
PeopleID = table.Column<long>(nullable: true),
|
PeopleID = table.Column<int>(nullable: true),
|
||||||
DataID = table.Column<string>(nullable: true),
|
DataID = table.Column<string>(nullable: true),
|
||||||
Link = table.Column<string>(nullable: true)
|
Link = table.Column<string>(nullable: true)
|
||||||
},
|
},
|
||||||
@ -378,14 +378,14 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
name: "Tracks",
|
name: "Tracks",
|
||||||
columns: table => new
|
columns: table => new
|
||||||
{
|
{
|
||||||
ID = table.Column<long>(nullable: false)
|
ID = table.Column<int>(nullable: false)
|
||||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||||
Title = table.Column<string>(nullable: true),
|
Title = table.Column<string>(nullable: true),
|
||||||
Language = table.Column<string>(nullable: true),
|
Language = table.Column<string>(nullable: true),
|
||||||
Codec = table.Column<string>(nullable: true),
|
Codec = table.Column<string>(nullable: true),
|
||||||
Path = table.Column<string>(nullable: true),
|
Path = table.Column<string>(nullable: true),
|
||||||
Type = table.Column<int>(nullable: false),
|
Type = table.Column<int>(nullable: false),
|
||||||
EpisodeID = table.Column<long>(nullable: false),
|
EpisodeID = table.Column<int>(nullable: false),
|
||||||
IsDefault = table.Column<bool>(nullable: false),
|
IsDefault = table.Column<bool>(nullable: false),
|
||||||
IsForced = table.Column<bool>(nullable: false),
|
IsForced = table.Column<bool>(nullable: false),
|
||||||
IsExternal = table.Column<bool>(nullable: false)
|
IsExternal = table.Column<bool>(nullable: false)
|
@ -21,9 +21,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Collection", b =>
|
modelBuilder.Entity("Kyoo.Models.Collection", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
@ -51,16 +51,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
|
modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long?>("CollectionID")
|
b.Property<int?>("CollectionID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -73,16 +73,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Episode", b =>
|
modelBuilder.Entity("Kyoo.Models.Episode", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long>("AbsoluteNumber")
|
b.Property<int>("AbsoluteNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("EpisodeNumber")
|
b.Property<int>("EpisodeNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -96,17 +96,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<DateTime?>("ReleaseDate")
|
b.Property<DateTime?>("ReleaseDate")
|
||||||
.HasColumnType("timestamp without time zone");
|
.HasColumnType("timestamp without time zone");
|
||||||
|
|
||||||
b.Property<long>("Runtime")
|
b.Property<int>("Runtime")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("SeasonID")
|
b.Property<int?>("SeasonID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("SeasonNumber")
|
b.Property<int>("SeasonNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -122,9 +122,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Genre", b =>
|
modelBuilder.Entity("Kyoo.Models.Genre", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -143,11 +143,11 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
|
modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("GenreID")
|
b.Property<int>("GenreID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ShowID", "GenreID");
|
b.HasKey("ShowID", "GenreID");
|
||||||
|
|
||||||
@ -158,9 +158,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Library", b =>
|
modelBuilder.Entity("Kyoo.Models.Library", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -182,19 +182,19 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
|
modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long?>("CollectionID")
|
b.Property<int?>("CollectionID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("LibraryID")
|
b.Property<int>("LibraryID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("ShowID")
|
b.Property<int?>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -209,31 +209,31 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.MetadataID", b =>
|
modelBuilder.Entity("Kyoo.Models.MetadataID", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("DataID")
|
b.Property<string>("DataID")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("EpisodeID")
|
b.Property<int?>("EpisodeID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Link")
|
b.Property<string>("Link")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("PeopleID")
|
b.Property<int?>("PeopleID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ProviderID")
|
b.Property<int>("ProviderID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("SeasonID")
|
b.Property<int?>("SeasonID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("ShowID")
|
b.Property<int?>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -252,9 +252,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.People", b =>
|
modelBuilder.Entity("Kyoo.Models.People", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
@ -276,19 +276,19 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
|
modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long>("PeopleID")
|
b.Property<int>("PeopleID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Role")
|
b.Property<string>("Role")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Type")
|
b.Property<string>("Type")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -304,9 +304,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
|
modelBuilder.Entity("Kyoo.Models.ProviderID", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Logo")
|
b.Property<string>("Logo")
|
||||||
@ -325,16 +325,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.ProviderLink", b =>
|
modelBuilder.Entity("Kyoo.Models.ProviderLink", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<long?>("LibraryID")
|
b.Property<int?>("LibraryID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ProviderID")
|
b.Property<int>("ProviderID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -347,9 +347,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Season", b =>
|
modelBuilder.Entity("Kyoo.Models.Season", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("ImgPrimary")
|
b.Property<string>("ImgPrimary")
|
||||||
@ -358,17 +358,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<string>("Overview")
|
b.Property<string>("Overview")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long>("SeasonNumber")
|
b.Property<int>("SeasonNumber")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long>("ShowID")
|
b.Property<int>("ShowID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("Year")
|
b.Property<int?>("Year")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.HasKey("ID");
|
b.HasKey("ID");
|
||||||
|
|
||||||
@ -379,9 +379,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Show", b =>
|
modelBuilder.Entity("Kyoo.Models.Show", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Aliases")
|
b.Property<string>("Aliases")
|
||||||
@ -390,8 +390,8 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<string>("Backdrop")
|
b.Property<string>("Backdrop")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("EndYear")
|
b.Property<int?>("EndYear")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<bool>("IsMovie")
|
b.Property<bool>("IsMovie")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
@ -411,14 +411,14 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
b.Property<string>("Slug")
|
b.Property<string>("Slug")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long?>("StartYear")
|
b.Property<int?>("StartYear")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<int?>("Status")
|
b.Property<int?>("Status")
|
||||||
.HasColumnType("integer");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<long?>("StudioID")
|
b.Property<int?>("StudioID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<string>("Title")
|
b.Property<string>("Title")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
@ -438,9 +438,9 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Studio", b =>
|
modelBuilder.Entity("Kyoo.Models.Studio", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Name")
|
b.Property<string>("Name")
|
||||||
@ -459,16 +459,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
|
|||||||
|
|
||||||
modelBuilder.Entity("Kyoo.Models.Track", b =>
|
modelBuilder.Entity("Kyoo.Models.Track", b =>
|
||||||
{
|
{
|
||||||
b.Property<long>("ID")
|
b.Property<int>("ID")
|
||||||
.ValueGeneratedOnAdd()
|
.ValueGeneratedOnAdd()
|
||||||
.HasColumnType("bigint")
|
.HasColumnType("integer")
|
||||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||||
|
|
||||||
b.Property<string>("Codec")
|
b.Property<string>("Codec")
|
||||||
.HasColumnType("text");
|
.HasColumnType("text");
|
||||||
|
|
||||||
b.Property<long>("EpisodeID")
|
b.Property<int>("EpisodeID")
|
||||||
.HasColumnType("bigint");
|
.HasColumnType("integer");
|
||||||
|
|
||||||
b.Property<bool>("IsDefault")
|
b.Property<bool>("IsDefault")
|
||||||
.HasColumnType("boolean");
|
.HasColumnType("boolean");
|
||||||
|
@ -137,6 +137,18 @@ namespace Kyoo
|
|||||||
AllowedOrigins = { new Uri(publicUrl).GetLeftPart(UriPartial.Authority) }
|
AllowedOrigins = { new Uri(publicUrl).GetLeftPart(UriPartial.Authority) }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
services.AddTransient<ILibraryRepository, LibraryRepository>();
|
||||||
|
services.AddTransient<ICollectionRepository, CollectionRepository>();
|
||||||
|
services.AddTransient<IShowRepository, ShowRepository>();
|
||||||
|
services.AddTransient<ISeasonRepository, SeasonRepository>();
|
||||||
|
services.AddTransient<IEpisodeRepository, EpisodeRepository>();
|
||||||
|
services.AddTransient<ITrackRepository, TrackRepository>();
|
||||||
|
services.AddTransient<IPeopleRepository, PeopleRepository>();
|
||||||
|
services.AddTransient<IStudioRepository, StudioRepository>();
|
||||||
|
services.AddTransient<IGenreRepository, GenreRepository>();
|
||||||
|
services.AddTransient<IProviderRepository, ProviderRepository>();
|
||||||
|
|
||||||
services.AddScoped<ILibraryManager, LibraryManager>();
|
services.AddScoped<ILibraryManager, LibraryManager>();
|
||||||
services.AddSingleton<ITranscoder, Transcoder>();
|
services.AddSingleton<ITranscoder, Transcoder>();
|
||||||
services.AddSingleton<IThumbnailsManager, ThumbnailsManager>();
|
services.AddSingleton<IThumbnailsManager, ThumbnailsManager>();
|
||||||
|
@ -8,7 +8,6 @@ using System.Text.RegularExpressions;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Models.Watch;
|
using Kyoo.Models.Watch;
|
||||||
using Microsoft.EntityFrameworkCore;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
@ -28,11 +27,11 @@ namespace Kyoo.Controllers
|
|||||||
private ITranscoder _transcoder;
|
private ITranscoder _transcoder;
|
||||||
private IConfiguration _config;
|
private IConfiguration _config;
|
||||||
|
|
||||||
public IEnumerable<string> GetPossibleParameters()
|
public async Task<IEnumerable<string>> GetPossibleParameters()
|
||||||
{
|
{
|
||||||
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
||||||
return libraryManager.GetLibraries().Select(x => x.Slug);
|
return (await libraryManager.GetLibraries()).Select(x => x.Slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? Progress()
|
public int? Progress()
|
||||||
@ -53,28 +52,27 @@ namespace Kyoo.Controllers
|
|||||||
{
|
{
|
||||||
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
||||||
IEnumerable<Episode> episodes = libraryManager.GetEpisodes();
|
ICollection<Episode> episodes = await libraryManager.GetEpisodes();
|
||||||
IEnumerable<Library> libraries = argument == null
|
ICollection<Library> libraries = argument == null
|
||||||
? libraryManager.GetLibraries()
|
? await libraryManager.GetLibraries()
|
||||||
: new [] {libraryManager.GetLibrary(argument)};
|
: new [] { await libraryManager.GetLibrary(argument)};
|
||||||
|
|
||||||
foreach (Episode episode in episodes)
|
foreach (Episode episode in episodes)
|
||||||
{
|
{
|
||||||
if (!File.Exists(episode.Path))
|
if (!File.Exists(episode.Path))
|
||||||
libraryManager.RemoveEpisode(episode);
|
await libraryManager.DeleteEpisode(episode);
|
||||||
}
|
}
|
||||||
await libraryManager.SaveChanges();
|
|
||||||
|
|
||||||
await Task.WhenAll(libraries.ToList().Select(x => Scan(x, libraryManager, cancellationToken)));
|
await Task.WhenAll(libraries.Select(x => Scan(x, episodes, cancellationToken)));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine($"Unknown exception thrown durring libraries scan.\nException: {ex.Message}");
|
await Console.Error.WriteLineAsync($"Unknown exception thrown durring libraries scan.\nException: {ex.Message}");
|
||||||
}
|
}
|
||||||
Console.WriteLine("Scan finished!");
|
Console.WriteLine("Scan finished!");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task Scan(Library library, ILibraryManager libraryManager, CancellationToken cancellationToken)
|
private Task Scan(Library library, ICollection<Episode> episodes, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"Scanning library {library.Name} at {string.Join(", ", library.Paths)}.");
|
Console.WriteLine($"Scanning library {library.Name} at {string.Join(", ", library.Paths)}.");
|
||||||
return Task.WhenAll(library.Paths.Select(async path =>
|
return Task.WhenAll(library.Paths.Select(async path =>
|
||||||
@ -89,29 +87,29 @@ namespace Kyoo.Controllers
|
|||||||
}
|
}
|
||||||
catch (DirectoryNotFoundException)
|
catch (DirectoryNotFoundException)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine($"The library's directory {path} could not be found (library slug: {library.Slug})");
|
await Console.Error.WriteLineAsync($"The library's directory {path} could not be found (library slug: {library.Slug})");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch (PathTooLongException)
|
catch (PathTooLongException)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine($"The library's directory {path} is too long for this system. (library slug: {library.Slug})");
|
await Console.Error.WriteLineAsync($"The library's directory {path} is too long for this system. (library slug: {library.Slug})");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine($"The library's directory {path} is invalid. (library slug: {library.Slug})");
|
await Console.Error.WriteLineAsync($"The library's directory {path} is invalid. (library slug: {library.Slug})");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
catch (UnauthorizedAccessException)
|
catch (UnauthorizedAccessException)
|
||||||
{
|
{
|
||||||
Console.Error.WriteLine($"Permission denied: can't access library's directory at {path}. (library slug: {library.Slug})");
|
await Console.Error.WriteLineAsync($"Permission denied: can't access library's directory at {path}. (library slug: {library.Slug})");
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return Task.WhenAll(files.Select(file =>
|
// return Task.WhenAll(files.Select(file =>
|
||||||
foreach (string file in files)
|
foreach (string file in files)
|
||||||
{
|
{
|
||||||
if (!IsVideo(file) || libraryManager.GetEpisodes().Any(x => x.Path == file))
|
if (!IsVideo(file) || episodes.Any(x => x.Path == file))
|
||||||
continue; //return Task.CompletedTask;
|
continue; //return Task.CompletedTask;
|
||||||
string relativePath = file.Substring(path.Length);
|
string relativePath = file.Substring(path.Length);
|
||||||
/*return*/ await RegisterFile(file, relativePath, library, cancellationToken);
|
/*return*/ await RegisterFile(file, relativePath, library, cancellationToken);
|
||||||
@ -128,7 +126,6 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
using IServiceScope serviceScope = _serviceProvider.CreateScope();
|
||||||
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
ILibraryManager libraryManager = serviceScope.ServiceProvider.GetService<ILibraryManager>();
|
||||||
((DbSet<Library>)libraryManager.GetLibraries()).Attach(library);
|
|
||||||
|
|
||||||
string patern = _config.GetValue<string>("regex");
|
string patern = _config.GetValue<string>("regex");
|
||||||
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
|
Regex regex = new Regex(patern, RegexOptions.IgnoreCase);
|
||||||
@ -137,74 +134,97 @@ namespace Kyoo.Controllers
|
|||||||
string showPath = Path.GetDirectoryName(path);
|
string showPath = Path.GetDirectoryName(path);
|
||||||
string collectionName = match.Groups["Collection"]?.Value;
|
string collectionName = match.Groups["Collection"]?.Value;
|
||||||
string showName = match.Groups["ShowTitle"].Value;
|
string showName = match.Groups["ShowTitle"].Value;
|
||||||
long seasonNumber = long.TryParse(match.Groups["Season"].Value, out long tmp) ? tmp : -1;
|
int seasonNumber = int.TryParse(match.Groups["Season"].Value, out int tmp) ? tmp : -1;
|
||||||
long episodeNumber = long.TryParse(match.Groups["Episode"].Value, out tmp) ? tmp : -1;
|
int episodeNumber = int.TryParse(match.Groups["Episode"].Value, out tmp) ? tmp : -1;
|
||||||
long absoluteNumber = long.TryParse(match.Groups["Absolute"].Value, out tmp) ? tmp : -1;
|
int absoluteNumber = int.TryParse(match.Groups["Absolute"].Value, out tmp) ? tmp : -1;
|
||||||
|
|
||||||
Collection collection = await GetCollection(libraryManager, collectionName, library);
|
Collection collection = await GetCollection(libraryManager, collectionName, library);
|
||||||
bool isMovie = seasonNumber == -1 && episodeNumber == -1 && absoluteNumber == -1;
|
bool isMovie = seasonNumber == -1 && episodeNumber == -1 && absoluteNumber == -1;
|
||||||
Show show = await GetShow(libraryManager, showName, showPath, isMovie, library);
|
Show show = await GetShow(libraryManager, showName, showPath, isMovie, library);
|
||||||
if (isMovie)
|
if (isMovie)
|
||||||
libraryManager.Register(await GetMovie(show, path));
|
await libraryManager.RegisterEpisode(await GetMovie(show, path));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Season season = await GetSeason(libraryManager, show, seasonNumber, library);
|
Season season = await GetSeason(libraryManager, show, seasonNumber, library);
|
||||||
Episode episode = await GetEpisode(libraryManager, show, season, episodeNumber, absoluteNumber, path, library);
|
Episode episode = await GetEpisode(libraryManager, show, season, episodeNumber, absoluteNumber, path, library);
|
||||||
libraryManager.Register(episode);
|
await libraryManager.RegisterEpisode(episode);
|
||||||
}
|
}
|
||||||
if (collection != null)
|
|
||||||
libraryManager.Register(collection);
|
await libraryManager.AddShowLink(show, library, collection);
|
||||||
libraryManager.RegisterShowLinks(library, collection, show);
|
Console.WriteLine($"Episode at {path} registered.");
|
||||||
Console.WriteLine($"Registering episode at: {path}");
|
|
||||||
await libraryManager.SaveChanges();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Collection> GetCollection(ILibraryManager libraryManager, string collectionName, Library library)
|
private async Task<Collection> GetCollection(ILibraryManager libraryManager,
|
||||||
|
string collectionName,
|
||||||
|
Library library)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(collectionName))
|
if (string.IsNullOrEmpty(collectionName))
|
||||||
return await Task.FromResult<Collection>(null);
|
return null;
|
||||||
Collection name = libraryManager.GetCollection(Utility.ToSlug(collectionName));
|
Collection collection = await libraryManager.GetCollection(Utility.ToSlug(collectionName));
|
||||||
if (name != null)
|
if (collection != null)
|
||||||
return name;
|
return collection;
|
||||||
return await _metadataProvider.GetCollectionFromName(collectionName, library);
|
collection = await _metadataProvider.GetCollectionFromName(collectionName, library);
|
||||||
|
await libraryManager.RegisterCollection(collection);
|
||||||
|
return collection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Show> GetShow(ILibraryManager libraryManager, string showTitle, string showPath, bool isMovie, Library library)
|
private async Task<Show> GetShow(ILibraryManager libraryManager,
|
||||||
|
string showTitle,
|
||||||
|
string showPath,
|
||||||
|
bool isMovie,
|
||||||
|
Library library)
|
||||||
{
|
{
|
||||||
Show show = libraryManager.GetShowByPath(showPath);
|
Show show = await libraryManager.GetShowByPath(showPath);
|
||||||
if (show != null)
|
if (show != null)
|
||||||
return show;
|
return show;
|
||||||
show = await _metadataProvider.SearchShow(showTitle, isMovie, library);
|
show = await _metadataProvider.SearchShow(showTitle, isMovie, library);
|
||||||
show.Path = showPath;
|
show.Path = showPath;
|
||||||
show.People = await _metadataProvider.GetPeople(show, library);
|
show.People = await _metadataProvider.GetPeople(show, library);
|
||||||
|
await libraryManager.RegisterShow(show);
|
||||||
await _thumbnailsManager.Validate(show.People);
|
await _thumbnailsManager.Validate(show.People);
|
||||||
await _thumbnailsManager.Validate(show);
|
await _thumbnailsManager.Validate(show);
|
||||||
return show;
|
return show;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Season> GetSeason(ILibraryManager libraryManager, Show show, long seasonNumber, Library library)
|
private async Task<Season> GetSeason(ILibraryManager libraryManager,
|
||||||
|
Show show,
|
||||||
|
int seasonNumber,
|
||||||
|
Library library)
|
||||||
{
|
{
|
||||||
if (seasonNumber == -1)
|
if (seasonNumber == -1)
|
||||||
return default;
|
return default;
|
||||||
Season season = libraryManager.GetSeason(show.Slug, seasonNumber);
|
Season season = await libraryManager.GetSeason(show.Slug, seasonNumber);
|
||||||
if (season == null)
|
if (season == null)
|
||||||
{
|
{
|
||||||
season = await _metadataProvider.GetSeason(show, seasonNumber, library);
|
season = await _metadataProvider.GetSeason(show, seasonNumber, library);
|
||||||
|
await libraryManager.RegisterSeason(season);
|
||||||
await _thumbnailsManager.Validate(season);
|
await _thumbnailsManager.Validate(season);
|
||||||
}
|
}
|
||||||
season.Show = show;
|
season.Show = show;
|
||||||
return season;
|
return season;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Episode> GetEpisode(ILibraryManager libraryManager, Show show, Season season, long episodeNumber, long absoluteNumber, string episodePath, Library library)
|
private async Task<Episode> GetEpisode(ILibraryManager libraryManager,
|
||||||
|
Show show,
|
||||||
|
Season season,
|
||||||
|
int episodeNumber,
|
||||||
|
int absoluteNumber,
|
||||||
|
string episodePath,
|
||||||
|
Library library)
|
||||||
{
|
{
|
||||||
Episode episode = await _metadataProvider.GetEpisode(show, episodePath, season?.SeasonNumber ?? -1, episodeNumber, absoluteNumber, library);
|
Episode episode = await _metadataProvider.GetEpisode(show,
|
||||||
if (season == null)
|
episodePath,
|
||||||
season = await GetSeason(libraryManager, show, episode.SeasonNumber, library);
|
season?.SeasonNumber ?? -1,
|
||||||
|
episodeNumber,
|
||||||
|
absoluteNumber,
|
||||||
|
library);
|
||||||
|
|
||||||
|
season ??= await GetSeason(libraryManager, show, episode.SeasonNumber, library);
|
||||||
episode.Season = season;
|
episode.Season = season;
|
||||||
|
episode.SeasonID = season?.ID;
|
||||||
if (season == null)
|
if (season == null)
|
||||||
{
|
{
|
||||||
await Console.Error.WriteLineAsync("\tError: You don't have any provider that support absolute epiode numbering. Install one and try again.");
|
await Console.Error.WriteLineAsync("Error: You don't have any provider that support absolute epiode numbering. Install one and try again.");
|
||||||
return default;
|
return default;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -215,7 +235,13 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
private async Task<Episode> GetMovie(Show show, string episodePath)
|
private async Task<Episode> GetMovie(Show show, string episodePath)
|
||||||
{
|
{
|
||||||
Episode episode = new Episode {Title = show.Title, Path = episodePath, Show = show};
|
Episode episode = new Episode
|
||||||
|
{
|
||||||
|
Title = show.Title,
|
||||||
|
Path = episodePath,
|
||||||
|
Show = show,
|
||||||
|
ShowID = show.ID
|
||||||
|
};
|
||||||
episode.Tracks = await GetTracks(episode);
|
episode.Tracks = await GetTracks(episode);
|
||||||
return episode;
|
return episode;
|
||||||
}
|
}
|
||||||
|
@ -58,9 +58,9 @@ namespace Kyoo.Tasks
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetPossibleParameters()
|
public Task<IEnumerable<string>> GetPossibleParameters()
|
||||||
{
|
{
|
||||||
return null;
|
return Task.FromResult<IEnumerable<string>>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? Progress()
|
public int? Progress()
|
||||||
|
@ -28,9 +28,9 @@ namespace Kyoo.Tasks
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetPossibleParameters()
|
public Task<IEnumerable<string>> GetPossibleParameters()
|
||||||
{
|
{
|
||||||
return null;
|
return Task.FromResult<IEnumerable<string>>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? Progress()
|
public int? Progress()
|
||||||
|
@ -24,9 +24,9 @@ namespace Kyoo.Tasks
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetPossibleParameters()
|
public Task<IEnumerable<string>> GetPossibleParameters()
|
||||||
{
|
{
|
||||||
return null;
|
return Task.FromResult<IEnumerable<string>>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? Progress()
|
public int? Progress()
|
||||||
|
@ -62,7 +62,7 @@ namespace Kyoo.Tasks
|
|||||||
edited.ID = old.ID;
|
edited.ID = old.ID;
|
||||||
edited.Slug = old.Slug;
|
edited.Slug = old.Slug;
|
||||||
edited.Path = old.Path;
|
edited.Path = old.Path;
|
||||||
await libraryManager.Edit(edited, true);
|
await libraryManager.EditShow(edited, true);
|
||||||
await _thumbnailsManager.Validate(edited, true);
|
await _thumbnailsManager.Validate(edited, true);
|
||||||
}
|
}
|
||||||
if (old.Seasons != null)
|
if (old.Seasons != null)
|
||||||
@ -95,7 +95,7 @@ namespace Kyoo.Tasks
|
|||||||
Library library = _database.LibraryLinks.First(x => x.Show == show && x.Library != null).Library;
|
Library library = _database.LibraryLinks.First(x => x.Show == show && x.Library != null).Library;
|
||||||
Season edited = await _providerManager.GetSeason(show, old.SeasonNumber, library);
|
Season edited = await _providerManager.GetSeason(show, old.SeasonNumber, library);
|
||||||
edited.ID = old.ID;
|
edited.ID = old.ID;
|
||||||
await libraryManager.Edit(edited, true);
|
await libraryManager.EditSeason(edited, true);
|
||||||
await _thumbnailsManager.Validate(edited, true);
|
await _thumbnailsManager.Validate(edited, true);
|
||||||
}
|
}
|
||||||
if (old.Episodes != null)
|
if (old.Episodes != null)
|
||||||
@ -110,13 +110,13 @@ namespace Kyoo.Tasks
|
|||||||
Library library = _database.LibraryLinks.First(x => x.Show == show && x.Library != null).Library;
|
Library library = _database.LibraryLinks.First(x => x.Show == show && x.Library != null).Library;
|
||||||
Episode edited = await _providerManager.GetEpisode(show, old.Path, old.SeasonNumber, old.EpisodeNumber, old.AbsoluteNumber, library);
|
Episode edited = await _providerManager.GetEpisode(show, old.Path, old.SeasonNumber, old.EpisodeNumber, old.AbsoluteNumber, library);
|
||||||
edited.ID = old.ID;
|
edited.ID = old.ID;
|
||||||
await libraryManager.Edit(edited, true);
|
await libraryManager.EditEpisode(edited, true);
|
||||||
await _thumbnailsManager.Validate(edited, true);
|
await _thumbnailsManager.Validate(edited, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<string> GetPossibleParameters()
|
public Task<IEnumerable<string>> GetPossibleParameters()
|
||||||
{
|
{
|
||||||
return default;
|
return Task.FromResult<IEnumerable<string>>(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int? Progress()
|
public int? Progress()
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
namespace Kyoo.Api
|
namespace Kyoo.Api
|
||||||
@ -19,9 +20,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{collectionSlug}")]
|
[HttpGet("{collectionSlug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public ActionResult<Collection> GetShows(string collectionSlug)
|
public async Task<ActionResult<Collection>> GetShows(string collectionSlug)
|
||||||
{
|
{
|
||||||
Collection collection = _libraryManager.GetCollection(collectionSlug);
|
Collection collection = await _libraryManager.GetCollection(collectionSlug);
|
||||||
|
|
||||||
if (collection == null)
|
if (collection == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
@ -20,9 +21,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{showSlug}/season/{seasonNumber}")]
|
[HttpGet("{showSlug}/season/{seasonNumber}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public ActionResult<IEnumerable<Episode>> GetEpisodesForSeason(string showSlug, long seasonNumber)
|
public async Task<ActionResult<IEnumerable<Episode>>> GetEpisodesForSeason(string showSlug, int seasonNumber)
|
||||||
{
|
{
|
||||||
IEnumerable<Episode> episodes = _libraryManager.GetEpisodes(showSlug, seasonNumber);
|
IEnumerable<Episode> episodes = await _libraryManager.GetEpisodes(showSlug, seasonNumber);
|
||||||
|
|
||||||
if(episodes == null)
|
if(episodes == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@ -33,9 +34,9 @@ namespace Kyoo.Api
|
|||||||
[HttpGet("{showSlug}/season/{seasonNumber}/episode/{episodeNumber}")]
|
[HttpGet("{showSlug}/season/{seasonNumber}/episode/{episodeNumber}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
[JsonDetailed]
|
[JsonDetailed]
|
||||||
public ActionResult<Episode> GetEpisode(string showSlug, long seasonNumber, long episodeNumber)
|
public async Task<ActionResult<Episode>> GetEpisode(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
Episode episode = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
|
|
||||||
if (episode == null)
|
if (episode == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -18,9 +19,9 @@ namespace Kyoo.API
|
|||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult<IEnumerable<Genre>> Index()
|
public async Task<ActionResult<IEnumerable<Genre>>> Index()
|
||||||
{
|
{
|
||||||
return _libraryManager.GetGenres().ToList();
|
return (await _libraryManager.GetGenres()).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ using Kyoo.Models;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
namespace Kyoo.Api
|
namespace Kyoo.Api
|
||||||
@ -22,15 +23,15 @@ namespace Kyoo.Api
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public IEnumerable<Library> GetLibraries()
|
public async Task<IEnumerable<Library>> GetLibraries()
|
||||||
{
|
{
|
||||||
return _libraryManager.GetLibraries();
|
return await _libraryManager.GetLibraries();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Route("/api/library/create")]
|
[Route("/api/library/create")]
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
[Authorize(Policy="Admin")]
|
[Authorize(Policy="Admin")]
|
||||||
public IActionResult CreateLibrary([FromBody] Library library)
|
public async Task<IActionResult> CreateLibrary([FromBody] Library library)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return BadRequest(library);
|
return BadRequest(library);
|
||||||
@ -40,19 +41,18 @@ namespace Kyoo.Api
|
|||||||
return BadRequest(new {error = "The library's name must be set and not empty"});
|
return BadRequest(new {error = "The library's name must be set and not empty"});
|
||||||
if (library.Paths == null || !library.Paths.Any())
|
if (library.Paths == null || !library.Paths.Any())
|
||||||
return BadRequest(new {error = "The library should have a least one path."});
|
return BadRequest(new {error = "The library should have a least one path."});
|
||||||
if (_libraryManager.GetLibrary(library.Slug) != null)
|
if (await _libraryManager.GetLibrary(library.Slug) != null)
|
||||||
return BadRequest(new {error = "Duplicated library slug"});
|
return BadRequest(new {error = "Duplicated library slug"});
|
||||||
_libraryManager.Register(library);
|
await _libraryManager.RegisterLibrary(library);
|
||||||
_libraryManager.SaveChanges();
|
|
||||||
_taskManager.StartTask("scan", library.Slug);
|
_taskManager.StartTask("scan", library.Slug);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{librarySlug}")]
|
[HttpGet("{librarySlug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public ActionResult<IEnumerable<Show>> GetShows(string librarySlug)
|
public async Task<ActionResult<IEnumerable<Show>>> GetShows(string librarySlug)
|
||||||
{
|
{
|
||||||
Library library = _libraryManager.GetLibrary(librarySlug);
|
Library library = await _libraryManager.GetLibrary(librarySlug);
|
||||||
|
|
||||||
if (library == null)
|
if (library == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
@ -19,9 +20,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{peopleSlug}")]
|
[HttpGet("{peopleSlug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public ActionResult<Collection> GetPeople(string peopleSlug)
|
public async Task<ActionResult<Collection>> GetPeople(string peopleSlug)
|
||||||
{
|
{
|
||||||
People people = _libraryManager.GetPeople(peopleSlug);
|
People people = await _libraryManager.GetPeople(peopleSlug);
|
||||||
|
|
||||||
if (people == null)
|
if (people == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Kyoo.Controllers;
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -18,17 +19,17 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{query}")]
|
[HttpGet("{query}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public ActionResult<SearchResult> Search(string query)
|
public async Task<ActionResult<SearchResult>> Search(string query)
|
||||||
{
|
{
|
||||||
SearchResult result = new SearchResult
|
SearchResult result = new SearchResult
|
||||||
{
|
{
|
||||||
Query = query,
|
Query = query,
|
||||||
Collections = _libraryManager.SearchCollections(query),
|
Collections = await _libraryManager.SearchCollections(query),
|
||||||
Shows = _libraryManager.SearchShows(query),
|
Shows = await _libraryManager.SearchShows(query),
|
||||||
Episodes = _libraryManager.SearchEpisodes(query),
|
Episodes = await _libraryManager.SearchEpisodes(query),
|
||||||
People = _libraryManager.SearchPeople(query),
|
People = await _libraryManager.SearchPeople(query),
|
||||||
Genres = _libraryManager.SearchGenres(query),
|
Genres = await _libraryManager.SearchGenres(query),
|
||||||
Studios = _libraryManager.SearchStudios(query)
|
Studios = await _libraryManager.SearchStudios(query)
|
||||||
};
|
};
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -37,15 +37,18 @@ namespace Kyoo.Api
|
|||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public IEnumerable<Show> GetShows()
|
public IEnumerable<Show> GetShows()
|
||||||
{
|
{
|
||||||
return _database.LibraryLinks.AsEnumerable().Select(x => x.Show ?? x.Collection.AsShow());
|
return _database.LibraryLinks
|
||||||
|
.Include(x => x.Show)
|
||||||
|
.Include(x => x.Collection)
|
||||||
|
.AsEnumerable().Select(x => x.Show ?? x.Collection.AsShow()).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{slug}")]
|
[HttpGet("{slug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
[JsonDetailed]
|
[JsonDetailed]
|
||||||
public ActionResult<Show> GetShow(string slug)
|
public async Task<ActionResult<Show>> GetShow(string slug)
|
||||||
{
|
{
|
||||||
Show show = _libraryManager.GetShow(slug);
|
Show show = await _libraryManager.GetShow(slug);
|
||||||
|
|
||||||
if (show == null)
|
if (show == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@ -55,7 +58,7 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpPost("edit/{slug}")]
|
[HttpPost("edit/{slug}")]
|
||||||
[Authorize(Policy="Write")]
|
[Authorize(Policy="Write")]
|
||||||
public IActionResult EditShow(string slug, [FromBody] Show show)
|
public async Task<IActionResult> EditShow(string slug, [FromBody] Show show)
|
||||||
{
|
{
|
||||||
if (!ModelState.IsValid)
|
if (!ModelState.IsValid)
|
||||||
return BadRequest(show);
|
return BadRequest(show);
|
||||||
@ -66,7 +69,7 @@ namespace Kyoo.Api
|
|||||||
show.ID = old.ID;
|
show.ID = old.ID;
|
||||||
show.Slug = slug;
|
show.Slug = slug;
|
||||||
show.Path = old.Path;
|
show.Path = old.Path;
|
||||||
_libraryManager.Edit(show, false);
|
await _libraryManager.EditShow(show, false);
|
||||||
return Ok();
|
return Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +82,6 @@ namespace Kyoo.Api
|
|||||||
Show show = _database.Shows.Include(x => x.ExternalIDs).FirstOrDefault(x => x.Slug == slug);
|
Show show = _database.Shows.Include(x => x.ExternalIDs).FirstOrDefault(x => x.Slug == slug);
|
||||||
if (show == null)
|
if (show == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
show.ExternalIDs = _libraryManager.Validate(externalIDs);
|
|
||||||
_database.SaveChanges();
|
_database.SaveChanges();
|
||||||
_taskManager.StartTask("re-scan", $"show/{slug}");
|
_taskManager.StartTask("re-scan", $"show/{slug}");
|
||||||
return Ok();
|
return Ok();
|
||||||
@ -96,7 +98,7 @@ namespace Kyoo.Api
|
|||||||
[Authorize(Policy = "Write")]
|
[Authorize(Policy = "Write")]
|
||||||
public async Task<IActionResult> DownloadImages(string slug)
|
public async Task<IActionResult> DownloadImages(string slug)
|
||||||
{
|
{
|
||||||
Show show = _libraryManager.GetShow(slug);
|
Show show = await _libraryManager.GetShow(slug);
|
||||||
if (show == null)
|
if (show == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
await _thumbnailsManager.Validate(show, true);
|
await _thumbnailsManager.Validate(show, true);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -18,9 +19,9 @@ namespace Kyoo.API
|
|||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionResult<IEnumerable<Studio>> Index()
|
public async Task<ActionResult<IEnumerable<Studio>>> Index()
|
||||||
{
|
{
|
||||||
return _libraryManager.GetStudios().ToList();
|
return (await _libraryManager.GetStudios()).ToList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -14,31 +14,37 @@ namespace Kyoo.Api
|
|||||||
public class SubtitleController : ControllerBase
|
public class SubtitleController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILibraryManager _libraryManager;
|
private readonly ILibraryManager _libraryManager;
|
||||||
private readonly ITranscoder _transcoder;
|
//private readonly ITranscoder _transcoder;
|
||||||
|
|
||||||
public SubtitleController(ILibraryManager libraryManager, ITranscoder transcoder)
|
public SubtitleController(ILibraryManager libraryManager/*, ITranscoder transcoder*/)
|
||||||
{
|
{
|
||||||
_libraryManager = libraryManager;
|
_libraryManager = libraryManager;
|
||||||
_transcoder = transcoder;
|
// _transcoder = transcoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{extension?}")]
|
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{extension?}")]
|
||||||
[Authorize(Policy="Play")]
|
[Authorize(Policy="Play")]
|
||||||
public IActionResult GetSubtitle(string showSlug, int seasonNumber, int episodeNumber, string identifier, string extension)
|
public async Task<IActionResult> GetSubtitle(string showSlug,
|
||||||
|
int seasonNumber,
|
||||||
|
int episodeNumber,
|
||||||
|
string identifier,
|
||||||
|
string extension)
|
||||||
{
|
{
|
||||||
string languageTag = identifier.Length == 3 ? identifier.Substring(0, 3) : null;
|
string languageTag = identifier.Length == 3 ? identifier.Substring(0, 3) : null;
|
||||||
bool forced = identifier.Length > 4 && identifier.Substring(4) == "forced";
|
bool forced = identifier.Length > 4 && identifier.Substring(4) == "forced";
|
||||||
Track subtitle = null;
|
Track subtitle = null;
|
||||||
|
|
||||||
if (languageTag != null)
|
if (languageTag != null)
|
||||||
subtitle = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber)?.Tracks
|
subtitle = (await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber))?.Tracks
|
||||||
.FirstOrDefault(x => x.Language == languageTag && x.IsForced == forced);
|
.FirstOrDefault(x => x.Language == languageTag && x.IsForced == forced);
|
||||||
|
|
||||||
if (subtitle == null)
|
if (subtitle == null)
|
||||||
{
|
{
|
||||||
string idString = identifier.IndexOf('-') != -1 ? identifier.Substring(0, identifier.IndexOf('-')) : identifier;
|
string idString = identifier.IndexOf('-') != -1
|
||||||
long.TryParse(idString, out long id);
|
? identifier.Substring(0, identifier.IndexOf('-'))
|
||||||
subtitle = _libraryManager.GetTracks().FirstOrDefault(x => x.ID == id);
|
: identifier;
|
||||||
|
int.TryParse(idString, out int id);
|
||||||
|
subtitle = await _libraryManager.GetTrack(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (subtitle == null)
|
if (subtitle == null)
|
||||||
@ -57,43 +63,43 @@ namespace Kyoo.Api
|
|||||||
return PhysicalFile(subtitle.Path, mime);
|
return PhysicalFile(subtitle.Path, mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("extract/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
// [HttpGet("extract/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||||
[Authorize(Policy="Admin")]
|
// [Authorize(Policy="Admin")]
|
||||||
public async Task<string> ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber)
|
// public async Task<string> ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber)
|
||||||
{
|
// {
|
||||||
Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
// Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
episode.Tracks = null;
|
// episode.Tracks = null;
|
||||||
|
//
|
||||||
Track[] tracks = await _transcoder.ExtractSubtitles(episode.Path);
|
// Track[] tracks = await _transcoder.ExtractSubtitles(episode.Path);
|
||||||
foreach (Track track in tracks)
|
// foreach (Track track in tracks)
|
||||||
{
|
// {
|
||||||
track.EpisodeID = episode.ID;
|
// track.EpisodeID = episode.ID;
|
||||||
_libraryManager.Register(track);
|
// _libraryManager.Register(track);
|
||||||
}
|
// }
|
||||||
await _libraryManager.SaveChanges();
|
// await _libraryManager.SaveChanges();
|
||||||
return "Done. " + tracks.Length + " track(s) extracted.";
|
// return "Done. " + tracks.Length + " track(s) extracted.";
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
[HttpGet("extract/{showSlug}")]
|
// [HttpGet("extract/{showSlug}")]
|
||||||
[Authorize(Policy="Admin")]
|
// [Authorize(Policy="Admin")]
|
||||||
public async Task<string> ExtractSubtitle(string showSlug)
|
// public async Task<string> ExtractSubtitle(string showSlug)
|
||||||
{
|
// {
|
||||||
IEnumerable<Episode> episodes = _libraryManager.GetShow(showSlug).Episodes;
|
// IEnumerable<Episode> episodes = _libraryManager.GetShow(showSlug).Episodes;
|
||||||
foreach (Episode episode in episodes)
|
// foreach (Episode episode in episodes)
|
||||||
{
|
// {
|
||||||
episode.Tracks = null;
|
// episode.Tracks = null;
|
||||||
|
//
|
||||||
Track[] tracks = await _transcoder.ExtractSubtitles(episode.Path);
|
// Track[] tracks = await _transcoder.ExtractSubtitles(episode.Path);
|
||||||
foreach (Track track in tracks)
|
// foreach (Track track in tracks)
|
||||||
{
|
// {
|
||||||
track.EpisodeID = episode.ID;
|
// track.EpisodeID = episode.ID;
|
||||||
_libraryManager.Register(track);
|
// _libraryManager.Register(track);
|
||||||
}
|
// }
|
||||||
await _libraryManager.SaveChanges();
|
// await _libraryManager.SaveChanges();
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return "Done.";
|
// return "Done.";
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
|
||||||
@ -20,9 +21,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("poster/{showSlug}")]
|
[HttpGet("poster/{showSlug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public IActionResult GetShowThumb(string showSlug)
|
public async Task<IActionResult> GetShowThumb(string showSlug)
|
||||||
{
|
{
|
||||||
string path = _libraryManager.GetShow(showSlug)?.Path;
|
string path = (await _libraryManager.GetShow(showSlug))?.Path;
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
@ -35,9 +36,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("logo/{showSlug}")]
|
[HttpGet("logo/{showSlug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public IActionResult GetShowLogo(string showSlug)
|
public async Task<IActionResult> GetShowLogo(string showSlug)
|
||||||
{
|
{
|
||||||
string path = _libraryManager.GetShow(showSlug)?.Path;
|
string path = (await _libraryManager.GetShow(showSlug))?.Path;
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
@ -50,9 +51,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("backdrop/{showSlug}")]
|
[HttpGet("backdrop/{showSlug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public IActionResult GetShowBackdrop(string showSlug)
|
public async Task<IActionResult> GetShowBackdrop(string showSlug)
|
||||||
{
|
{
|
||||||
string path = _libraryManager.GetShow(showSlug)?.Path;
|
string path = (await _libraryManager.GetShow(showSlug))?.Path;
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
@ -76,9 +77,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("thumb/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
[HttpGet("thumb/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public IActionResult GetEpisodeThumb(string showSlug, long seasonNumber, long episodeNumber)
|
public async Task<IActionResult> GetEpisodeThumb(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
string path = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber)?.Path;
|
string path = (await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber))?.Path;
|
||||||
if (path == null)
|
if (path == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||||
[Authorize(Policy="Play")]
|
[Authorize(Policy="Play")]
|
||||||
public IActionResult Index(string showSlug, long seasonNumber, long episodeNumber)
|
public async Task<IActionResult> Index(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
Episode episode = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
|
|
||||||
if (episode != null && System.IO.File.Exists(episode.Path))
|
if (episode != null && System.IO.File.Exists(episode.Path))
|
||||||
return PhysicalFile(episode.Path, "video/x-matroska", true);
|
return PhysicalFile(episode.Path, "video/x-matroska", true);
|
||||||
@ -38,9 +38,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("transmux/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
[HttpGet("transmux/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||||
[Authorize(Policy="Play")]
|
[Authorize(Policy="Play")]
|
||||||
public async Task<IActionResult> Transmux(string showSlug, long seasonNumber, long episodeNumber)
|
public async Task<IActionResult> Transmux(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
Episode episode = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
|
|
||||||
if (episode == null || !System.IO.File.Exists(episode.Path))
|
if (episode == null || !System.IO.File.Exists(episode.Path))
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@ -61,9 +61,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("transcode/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
[HttpGet("transcode/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||||
[Authorize(Policy="Play")]
|
[Authorize(Policy="Play")]
|
||||||
public async Task<IActionResult> Transcode(string showSlug, long seasonNumber, long episodeNumber)
|
public async Task<IActionResult> Transcode(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
Episode episode = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
Episode episode = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
|
|
||||||
if (episode == null || !System.IO.File.Exists(episode.Path))
|
if (episode == null || !System.IO.File.Exists(episode.Path))
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@ -85,9 +85,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{movieSlug}")]
|
[HttpGet("{movieSlug}")]
|
||||||
[Authorize(Policy="Play")]
|
[Authorize(Policy="Play")]
|
||||||
public IActionResult Index(string movieSlug)
|
public async Task<IActionResult> Index(string movieSlug)
|
||||||
{
|
{
|
||||||
Episode episode = _libraryManager.GetMovieEpisode(movieSlug);
|
Episode episode = await _libraryManager.GetMovieEpisode(movieSlug);
|
||||||
|
|
||||||
if (episode != null && System.IO.File.Exists(episode.Path))
|
if (episode != null && System.IO.File.Exists(episode.Path))
|
||||||
return PhysicalFile(episode.Path, "video/webm", true);
|
return PhysicalFile(episode.Path, "video/webm", true);
|
||||||
@ -98,7 +98,7 @@ namespace Kyoo.Api
|
|||||||
[Authorize(Policy="Play")]
|
[Authorize(Policy="Play")]
|
||||||
public async Task<IActionResult> Transmux(string movieSlug)
|
public async Task<IActionResult> Transmux(string movieSlug)
|
||||||
{
|
{
|
||||||
Episode episode = _libraryManager.GetMovieEpisode(movieSlug);
|
Episode episode = await _libraryManager.GetMovieEpisode(movieSlug);
|
||||||
|
|
||||||
if (episode == null || !System.IO.File.Exists(episode.Path))
|
if (episode == null || !System.IO.File.Exists(episode.Path))
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@ -112,7 +112,7 @@ namespace Kyoo.Api
|
|||||||
[Authorize(Policy="Play")]
|
[Authorize(Policy="Play")]
|
||||||
public async Task<IActionResult> Transcode(string movieSlug)
|
public async Task<IActionResult> Transcode(string movieSlug)
|
||||||
{
|
{
|
||||||
Episode episode = _libraryManager.GetMovieEpisode(movieSlug);
|
Episode episode = await _libraryManager.GetMovieEpisode(movieSlug);
|
||||||
|
|
||||||
if (episode == null || !System.IO.File.Exists(episode.Path))
|
if (episode == null || !System.IO.File.Exists(episode.Path))
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using Kyoo.Controllers;
|
using System.Threading.Tasks;
|
||||||
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Microsoft.AspNetCore.Authorization;
|
using Microsoft.AspNetCore.Authorization;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
@ -18,9 +19,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public ActionResult<WatchItem> Index(string showSlug, long seasonNumber, long episodeNumber)
|
public async Task<ActionResult<WatchItem>> Index(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
Episode item = _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
Episode item = await _libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
|
|
||||||
if(item == null)
|
if(item == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
@ -30,9 +31,9 @@ namespace Kyoo.Api
|
|||||||
|
|
||||||
[HttpGet("{movieSlug}")]
|
[HttpGet("{movieSlug}")]
|
||||||
[Authorize(Policy="Read")]
|
[Authorize(Policy="Read")]
|
||||||
public ActionResult<WatchItem> Index(string movieSlug)
|
public async Task<ActionResult<WatchItem>> Index(string movieSlug)
|
||||||
{
|
{
|
||||||
Episode item = _libraryManager.GetMovieEpisode(movieSlug);
|
Episode item = await _libraryManager.GetMovieEpisode(movieSlug);
|
||||||
|
|
||||||
if(item == null)
|
if(item == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user