mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-08 10:44:20 -04:00
Fixing composed slug handling & page field serialization
This commit is contained in:
parent
fab9a3f6a1
commit
b3fdee4bcd
@ -109,6 +109,8 @@ namespace Kyoo.Controllers
|
|||||||
public interface IShowRepository : IRepository<Show>
|
public interface IShowRepository : IRepository<Show>
|
||||||
{
|
{
|
||||||
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
Task AddShowLink(int showID, int? libraryID, int? collectionID);
|
||||||
|
|
||||||
|
Task<string> GetSlug(int showID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ISeasonRepository : IRepository<Season>
|
public interface ISeasonRepository : IRepository<Season>
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace Kyoo.Models.Attributes
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class ComposedSlugAttribute : Attribute { }
|
|
||||||
}
|
|
@ -5,11 +5,11 @@ using Kyoo.Models.Attributes;
|
|||||||
|
|
||||||
namespace Kyoo.Models
|
namespace Kyoo.Models
|
||||||
{
|
{
|
||||||
[ComposedSlug]
|
|
||||||
public class Episode : IResource, IOnMerge
|
public class Episode : IResource, IOnMerge
|
||||||
{
|
{
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
public string Slug => Show != null ? GetSlug(Show.Slug, SeasonNumber, EpisodeNumber) : ID.ToString();
|
public string Slug => GetSlug(ShowSlug, SeasonNumber, EpisodeNumber);
|
||||||
|
[SerializeIgnore] public string ShowSlug { private get; set; }
|
||||||
[SerializeIgnore] public int ShowID { get; set; }
|
[SerializeIgnore] public int ShowID { get; set; }
|
||||||
[LoadableRelation(nameof(ShowID))] public virtual Show Show { get; set; }
|
[LoadableRelation(nameof(ShowID))] public virtual Show Show { get; set; }
|
||||||
[SerializeIgnore] public int? SeasonID { get; set; }
|
[SerializeIgnore] public int? SeasonID { get; set; }
|
||||||
@ -30,9 +30,7 @@ namespace Kyoo.Models
|
|||||||
[LoadableRelation] public virtual ICollection<MetadataID> ExternalIDs { get; set; }
|
[LoadableRelation] public virtual ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
[LoadableRelation] public virtual ICollection<Track> Tracks { get; set; }
|
[LoadableRelation] public virtual ICollection<Track> Tracks { get; set; }
|
||||||
|
|
||||||
public string ShowTitle => Show?.Title;
|
|
||||||
|
|
||||||
|
|
||||||
public Episode() { }
|
public Episode() { }
|
||||||
|
|
||||||
@ -78,6 +76,8 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public static string GetSlug(string showSlug, int seasonNumber, int episodeNumber)
|
public static string GetSlug(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
|
if (showSlug == null)
|
||||||
|
throw new ArgumentException("Show's slug is null. Can't find episode's slug.");
|
||||||
if (seasonNumber == -1)
|
if (seasonNumber == -1)
|
||||||
return showSlug;
|
return showSlug;
|
||||||
return $"{showSlug}-s{seasonNumber}e{episodeNumber}";
|
return $"{showSlug}-s{seasonNumber}e{episodeNumber}";
|
||||||
|
@ -4,15 +4,16 @@ using Kyoo.Models.Attributes;
|
|||||||
|
|
||||||
namespace Kyoo.Models
|
namespace Kyoo.Models
|
||||||
{
|
{
|
||||||
[ComposedSlug]
|
|
||||||
public class Season : IResource
|
public class Season : IResource
|
||||||
{
|
{
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
|
public string Slug => $"{ShowSlug}-s{SeasonNumber}";
|
||||||
[SerializeIgnore] public int ShowID { get; set; }
|
[SerializeIgnore] public int ShowID { get; set; }
|
||||||
|
[SerializeIgnore] public string ShowSlug { private get; set; }
|
||||||
|
[LoadableRelation(nameof(ShowID))] public virtual Show Show { get; set; }
|
||||||
|
|
||||||
public int SeasonNumber { get; set; } = -1;
|
public int SeasonNumber { get; set; } = -1;
|
||||||
|
|
||||||
public string Slug => Show != null ? $"{Show.Slug}-s{SeasonNumber}" : ID.ToString();
|
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
public string Overview { get; set; }
|
public string Overview { get; set; }
|
||||||
public int? Year { get; set; }
|
public int? Year { get; set; }
|
||||||
@ -21,7 +22,6 @@ namespace Kyoo.Models
|
|||||||
public string Thumb => $"/api/seasons/{Slug}/thumb";
|
public string Thumb => $"/api/seasons/{Slug}/thumb";
|
||||||
[EditableRelation] [LoadableRelation] public virtual ICollection<MetadataID> ExternalIDs { get; set; }
|
[EditableRelation] [LoadableRelation] public virtual ICollection<MetadataID> ExternalIDs { get; set; }
|
||||||
|
|
||||||
[LoadableRelation(nameof(ShowID))] public virtual Show Show { get; set; }
|
|
||||||
[LoadableRelation] public virtual ICollection<Episode> Episodes { get; set; }
|
[LoadableRelation] public virtual ICollection<Episode> Episodes { get; set; }
|
||||||
|
|
||||||
public Season() { }
|
public Season() { }
|
||||||
|
@ -25,7 +25,7 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public class WatchItem
|
public class WatchItem
|
||||||
{
|
{
|
||||||
public readonly int EpisodeID = -1;
|
public readonly int EpisodeID;
|
||||||
|
|
||||||
public string ShowTitle;
|
public string ShowTitle;
|
||||||
public string ShowSlug;
|
public string ShowSlug;
|
||||||
@ -41,9 +41,9 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public string Container;
|
public string Container;
|
||||||
public Track Video;
|
public Track Video;
|
||||||
public IEnumerable<Track> Audios;
|
public ICollection<Track> Audios;
|
||||||
public IEnumerable<Track> Subtitles;
|
public ICollection<Track> Subtitles;
|
||||||
public IEnumerable<Chapter> Chapters;
|
public ICollection<Chapter> Chapters;
|
||||||
|
|
||||||
public WatchItem() { }
|
public WatchItem() { }
|
||||||
|
|
||||||
@ -78,8 +78,8 @@ namespace Kyoo.Models
|
|||||||
DateTime? releaseDate,
|
DateTime? releaseDate,
|
||||||
string path,
|
string path,
|
||||||
Track video,
|
Track video,
|
||||||
IEnumerable<Track> audios,
|
ICollection<Track> audios,
|
||||||
IEnumerable<Track> subtitles)
|
ICollection<Track> subtitles)
|
||||||
: this(episodeID, showTitle, showSlug, seasonNumber, episodeNumber, title, releaseDate, path)
|
: this(episodeID, showTitle, showSlug, seasonNumber, episodeNumber, title, releaseDate, path)
|
||||||
{
|
{
|
||||||
Video = video;
|
Video = video;
|
||||||
@ -120,8 +120,8 @@ namespace Kyoo.Models
|
|||||||
ep.ReleaseDate,
|
ep.ReleaseDate,
|
||||||
ep.Path,
|
ep.Path,
|
||||||
ep.Tracks.FirstOrDefault(x => x.Type == StreamType.Video),
|
ep.Tracks.FirstOrDefault(x => x.Type == StreamType.Video),
|
||||||
ep.Tracks.Where(x => x.Type == StreamType.Audio),
|
ep.Tracks.Where(x => x.Type == StreamType.Audio).ToArray(),
|
||||||
ep.Tracks.Where(x => x.Type == StreamType.Subtitle))
|
ep.Tracks.Where(x => x.Type == StreamType.Subtitle).ToArray())
|
||||||
{
|
{
|
||||||
IsMovie = show.IsMovie,
|
IsMovie = show.IsMovie,
|
||||||
PreviousEpisode = previous,
|
PreviousEpisode = previous,
|
||||||
@ -130,7 +130,7 @@ namespace Kyoo.Models
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task<IEnumerable<Chapter>> GetChapters(string episodePath)
|
private static async Task<ICollection<Chapter>> GetChapters(string episodePath)
|
||||||
{
|
{
|
||||||
string path = PathIO.Combine(
|
string path = PathIO.Combine(
|
||||||
PathIO.GetDirectoryName(episodePath)!,
|
PathIO.GetDirectoryName(episodePath)!,
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Attributes;
|
using Kyoo.Models.Attributes;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Serialization;
|
using Newtonsoft.Json.Serialization;
|
||||||
@ -40,8 +42,13 @@ namespace Kyoo.Controllers
|
|||||||
protected override JsonContract CreateContract(Type objectType)
|
protected override JsonContract CreateContract(Type objectType)
|
||||||
{
|
{
|
||||||
JsonContract contract = base.CreateContract(objectType);
|
JsonContract contract = base.CreateContract(objectType);
|
||||||
contract.OnSerializingCallbacks.Add((_, _) => _depth++);
|
if (Utility.GetGenericDefinition(objectType, typeof(Page<>)) == null
|
||||||
contract.OnSerializedCallbacks.Add((_, _) => _depth--);
|
&& !objectType.IsAssignableTo(typeof(IEnumerable)))
|
||||||
|
{
|
||||||
|
contract.OnSerializingCallbacks.Add((_, _) => _depth++);
|
||||||
|
contract.OnSerializedCallbacks.Add((_, _) => _depth--);
|
||||||
|
}
|
||||||
|
|
||||||
return contract;
|
return contract;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ namespace Kyoo.Controllers
|
|||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(resource.Slug))
|
if (string.IsNullOrEmpty(resource.Slug))
|
||||||
throw new ArgumentException("Resource can't have null as a slug.");
|
throw new ArgumentException("Resource can't have null as a slug.");
|
||||||
if (int.TryParse(resource.Slug, out int _) && typeof(T).GetCustomAttribute<ComposedSlugAttribute>() == null)
|
if (int.TryParse(resource.Slug, out int _))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -5,7 +5,6 @@ using System.Linq.Expressions;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Exceptions;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
@ -15,13 +14,16 @@ namespace Kyoo.Controllers
|
|||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
private readonly IProviderRepository _providers;
|
private readonly IProviderRepository _providers;
|
||||||
|
private readonly IShowRepository _shows;
|
||||||
protected override Expression<Func<Episode, object>> DefaultSort => x => x.EpisodeNumber;
|
protected override Expression<Func<Episode, object>> DefaultSort => x => x.EpisodeNumber;
|
||||||
|
|
||||||
|
|
||||||
public EpisodeRepository(DatabaseContext database, IProviderRepository providers) : base(database)
|
public EpisodeRepository(DatabaseContext database, IProviderRepository providers, IShowRepository shows)
|
||||||
|
: base(database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_providers = providers;
|
_providers = providers;
|
||||||
|
_shows = shows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -32,6 +34,7 @@ namespace Kyoo.Controllers
|
|||||||
_disposed = true;
|
_disposed = true;
|
||||||
_database.Dispose();
|
_database.Dispose();
|
||||||
_providers.Dispose();
|
_providers.Dispose();
|
||||||
|
_shows.Dispose();
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,6 +45,15 @@ namespace Kyoo.Controllers
|
|||||||
_disposed = true;
|
_disposed = true;
|
||||||
await _database.DisposeAsync();
|
await _database.DisposeAsync();
|
||||||
await _providers.DisposeAsync();
|
await _providers.DisposeAsync();
|
||||||
|
await _shows.DisposeAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<Episode> Get(int id)
|
||||||
|
{
|
||||||
|
Episode ret = await base.Get(id);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = await _shows.GetSlug(ret.ShowID);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Task<Episode> Get(string slug)
|
public override Task<Episode> Get(string slug)
|
||||||
@ -54,45 +66,81 @@ namespace Kyoo.Controllers
|
|||||||
int.Parse(match.Groups["season"].Value),
|
int.Parse(match.Groups["season"].Value),
|
||||||
int.Parse(match.Groups["episode"].Value));
|
int.Parse(match.Groups["episode"].Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Episode> Get(string showSlug, int seasonNumber, int episodeNumber)
|
public override async Task<Episode> Get(Expression<Func<Episode, bool>> predicate)
|
||||||
{
|
{
|
||||||
return _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
Episode ret = await base.Get(predicate);
|
||||||
&& x.SeasonNumber == seasonNumber
|
if (ret != null)
|
||||||
&& x.EpisodeNumber == episodeNumber);
|
ret.ShowSlug = await _shows.GetSlug(ret.ShowID);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Episode> Get(int showID, int seasonNumber, int episodeNumber)
|
public async Task<Episode> Get(string showSlug, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
return _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
|
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
||||||
&& x.SeasonNumber == seasonNumber
|
&& x.SeasonNumber == seasonNumber
|
||||||
&& x.EpisodeNumber == episodeNumber);
|
&& x.EpisodeNumber == episodeNumber);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = showSlug;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Episode> Get(int seasonID, int episodeNumber)
|
public async Task<Episode> Get(int showID, int seasonNumber, int episodeNumber)
|
||||||
{
|
{
|
||||||
return _database.Episodes.FirstOrDefaultAsync(x => x.SeasonID == seasonID
|
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
|
||||||
&& x.EpisodeNumber == episodeNumber);
|
&& x.SeasonNumber == seasonNumber
|
||||||
|
&& x.EpisodeNumber == episodeNumber);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = await _shows.GetSlug(showID);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Episode> GetAbsolute(int showID, int absoluteNumber)
|
public async Task<Episode> Get(int seasonID, int episodeNumber)
|
||||||
{
|
{
|
||||||
return _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
|
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.SeasonID == seasonID
|
||||||
&& x.AbsoluteNumber == absoluteNumber);
|
&& x.EpisodeNumber == episodeNumber);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = await _shows.GetSlug(ret.ShowID);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Episode> GetAbsolute(string showSlug, int absoluteNumber)
|
public async Task<Episode> GetAbsolute(int showID, int absoluteNumber)
|
||||||
{
|
{
|
||||||
return _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
|
||||||
&& x.AbsoluteNumber == absoluteNumber);
|
&& x.AbsoluteNumber == absoluteNumber);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = await _shows.GetSlug(showID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<Episode> GetAbsolute(string showSlug, int absoluteNumber)
|
||||||
|
{
|
||||||
|
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
||||||
|
&& x.AbsoluteNumber == absoluteNumber);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = showSlug;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<ICollection<Episode>> Search(string query)
|
public override async Task<ICollection<Episode>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.Episodes
|
List<Episode> episodes = await _database.Episodes
|
||||||
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
foreach (Episode episode in episodes)
|
||||||
|
episode.ShowSlug = await _shows.GetSlug(episode.ShowID);
|
||||||
|
return episodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<ICollection<Episode>> GetAll(Expression<Func<Episode, bool>> where = null,
|
||||||
|
Sort<Episode> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
ICollection<Episode> episodes = await base.GetAll(where, sort, limit);
|
||||||
|
foreach (Episode episode in episodes)
|
||||||
|
episode.ShowSlug = await _shows.GetSlug(episode.ShowID);
|
||||||
|
return episodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<Episode> Create(Episode obj)
|
public override async Task<Episode> Create(Episode obj)
|
||||||
|
@ -5,7 +5,6 @@ using System.Linq.Expressions;
|
|||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Exceptions;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
@ -16,17 +15,20 @@ namespace Kyoo.Controllers
|
|||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
private readonly DatabaseContext _database;
|
private readonly DatabaseContext _database;
|
||||||
private readonly IProviderRepository _providers;
|
private readonly IProviderRepository _providers;
|
||||||
|
private readonly IShowRepository _shows;
|
||||||
private readonly Lazy<IEpisodeRepository> _episodes;
|
private readonly Lazy<IEpisodeRepository> _episodes;
|
||||||
protected override Expression<Func<Season, object>> DefaultSort => x => x.SeasonNumber;
|
protected override Expression<Func<Season, object>> DefaultSort => x => x.SeasonNumber;
|
||||||
|
|
||||||
|
|
||||||
public SeasonRepository(DatabaseContext database,
|
public SeasonRepository(DatabaseContext database,
|
||||||
IProviderRepository providers,
|
IProviderRepository providers,
|
||||||
|
IShowRepository shows,
|
||||||
IServiceProvider services)
|
IServiceProvider services)
|
||||||
: base(database)
|
: base(database)
|
||||||
{
|
{
|
||||||
_database = database;
|
_database = database;
|
||||||
_providers = providers;
|
_providers = providers;
|
||||||
|
_shows = shows;
|
||||||
_episodes = new Lazy<IEpisodeRepository>(services.GetRequiredService<IEpisodeRepository>);
|
_episodes = new Lazy<IEpisodeRepository>(services.GetRequiredService<IEpisodeRepository>);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,6 +40,7 @@ namespace Kyoo.Controllers
|
|||||||
_disposed = true;
|
_disposed = true;
|
||||||
_database.Dispose();
|
_database.Dispose();
|
||||||
_providers.Dispose();
|
_providers.Dispose();
|
||||||
|
_shows.Dispose();
|
||||||
if (_episodes.IsValueCreated)
|
if (_episodes.IsValueCreated)
|
||||||
_episodes.Value.Dispose();
|
_episodes.Value.Dispose();
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
@ -50,10 +53,27 @@ namespace Kyoo.Controllers
|
|||||||
_disposed = true;
|
_disposed = true;
|
||||||
await _database.DisposeAsync();
|
await _database.DisposeAsync();
|
||||||
await _providers.DisposeAsync();
|
await _providers.DisposeAsync();
|
||||||
|
await _shows.DisposeAsync();
|
||||||
if (_episodes.IsValueCreated)
|
if (_episodes.IsValueCreated)
|
||||||
await _episodes.Value.DisposeAsync();
|
await _episodes.Value.DisposeAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override async Task<Season> Get(int id)
|
||||||
|
{
|
||||||
|
Season ret = await base.Get(id);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = await _shows.GetSlug(ret.ShowID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<Season> Get(Expression<Func<Season, bool>> predicate)
|
||||||
|
{
|
||||||
|
Season ret = await base.Get(predicate);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = await _shows.GetSlug(ret.ShowID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
public override Task<Season> Get(string slug)
|
public override Task<Season> Get(string slug)
|
||||||
{
|
{
|
||||||
Match match = Regex.Match(slug, @"(?<show>.*)-s(?<season>\d*)");
|
Match match = Regex.Match(slug, @"(?<show>.*)-s(?<season>\d*)");
|
||||||
@ -63,24 +83,43 @@ namespace Kyoo.Controllers
|
|||||||
return Get(match.Groups["show"].Value, int.Parse(match.Groups["season"].Value));
|
return Get(match.Groups["show"].Value, int.Parse(match.Groups["season"].Value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Season> Get(int showID, int seasonNumber)
|
public async Task<Season> Get(int showID, int seasonNumber)
|
||||||
{
|
{
|
||||||
return _database.Seasons.FirstOrDefaultAsync(x => x.ShowID == showID
|
Season ret = await _database.Seasons.FirstOrDefaultAsync(x => x.ShowID == showID
|
||||||
&& x.SeasonNumber == seasonNumber);
|
&& x.SeasonNumber == seasonNumber);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = await _shows.GetSlug(showID);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Season> Get(string showSlug, int seasonNumber)
|
public async Task<Season> Get(string showSlug, int seasonNumber)
|
||||||
{
|
{
|
||||||
return _database.Seasons.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
Season ret = await _database.Seasons.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
|
||||||
&& x.SeasonNumber == seasonNumber);
|
&& x.SeasonNumber == seasonNumber);
|
||||||
|
if (ret != null)
|
||||||
|
ret.ShowSlug = showSlug;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<ICollection<Season>> Search(string query)
|
public override async Task<ICollection<Season>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.Seasons
|
List<Season> seasons = await _database.Seasons
|
||||||
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
.Where(x => EF.Functions.ILike(x.Title, $"%{query}%"))
|
||||||
.Take(20)
|
.Take(20)
|
||||||
.ToListAsync();
|
.ToListAsync();
|
||||||
|
foreach (Season season in seasons)
|
||||||
|
season.ShowSlug = await _shows.GetSlug(season.ShowID);
|
||||||
|
return seasons;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task<ICollection<Season>> GetAll(Expression<Func<Season, bool>> where = null,
|
||||||
|
Sort<Season> sort = default,
|
||||||
|
Pagination limit = default)
|
||||||
|
{
|
||||||
|
ICollection<Season> seasons = await base.GetAll(where, sort, limit);
|
||||||
|
foreach (Season season in seasons)
|
||||||
|
season.ShowSlug = await _shows.GetSlug(season.ShowID);
|
||||||
|
return seasons;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<Season> Create(Season obj)
|
public override async Task<Season> Create(Season obj)
|
||||||
|
@ -151,6 +151,13 @@ namespace Kyoo.Controllers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Task<string> GetSlug(int showID)
|
||||||
|
{
|
||||||
|
return _database.Shows.Where(x => x.ID == showID)
|
||||||
|
.Select(x => x.Slug)
|
||||||
|
.FirstOrDefaultAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public override async Task Delete(Show obj)
|
public override async Task Delete(Show obj)
|
||||||
{
|
{
|
||||||
if (obj == null)
|
if (obj == null)
|
||||||
|
@ -82,7 +82,7 @@ namespace Kyoo.Controllers
|
|||||||
{
|
{
|
||||||
if (obj.EpisodeID <= 0)
|
if (obj.EpisodeID <= 0)
|
||||||
{
|
{
|
||||||
obj.EpisodeID = obj.Episode?.ID ?? -1;
|
obj.EpisodeID = obj.Episode?.ID ?? 0;
|
||||||
if (obj.EpisodeID <= 0)
|
if (obj.EpisodeID <= 0)
|
||||||
throw new InvalidOperationException($"Can't store a track not related to any episode (episodeID: {obj.EpisodeID}).");
|
throw new InvalidOperationException($"Can't store a track not related to any episode (episodeID: {obj.EpisodeID}).");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user