diff --git a/Kyoo.Common/Controllers/IRepository.cs b/Kyoo.Common/Controllers/IRepository.cs
index fbe20a95..d4485716 100644
--- a/Kyoo.Common/Controllers/IRepository.cs
+++ b/Kyoo.Common/Controllers/IRepository.cs
@@ -375,14 +375,6 @@ namespace Kyoo.Controllers
/// If the item is not found
/// The episode found
Task Get(string showSlug, int seasonNumber, int episodeNumber);
- ///
- /// Get a episode from it's season ID and it's episode number.
- ///
- /// The ID of the season
- /// The episode number
- /// If the item is not found
- /// The episode found
- Task Get(int seasonID, int episodeNumber);
///
/// Get a episode from it's showID, it's seasonNumber and it's episode number or null if it is not found.
diff --git a/Kyoo.CommonAPI/LocalRepository.cs b/Kyoo.CommonAPI/LocalRepository.cs
index 8f82093e..8e78964f 100644
--- a/Kyoo.CommonAPI/LocalRepository.cs
+++ b/Kyoo.CommonAPI/LocalRepository.cs
@@ -97,19 +97,19 @@ namespace Kyoo.Controllers
}
///
- public Task GetOrDefault(int id)
+ public virtual Task GetOrDefault(int id)
{
return Database.Set().FirstOrDefaultAsync(x => x.ID == id);
}
///
- public Task GetOrDefault(string slug)
+ public virtual Task GetOrDefault(string slug)
{
return Database.Set().FirstOrDefaultAsync(x => x.Slug == slug);
}
///
- public Task GetOrDefault(Expression> where)
+ public virtual Task GetOrDefault(Expression> where)
{
return Database.Set().FirstOrDefaultAsync(where);
}
diff --git a/Kyoo/Controllers/Repositories/EpisodeRepository.cs b/Kyoo/Controllers/Repositories/EpisodeRepository.cs
index 84232067..fc384904 100644
--- a/Kyoo/Controllers/Repositories/EpisodeRepository.cs
+++ b/Kyoo/Controllers/Repositories/EpisodeRepository.cs
@@ -5,21 +5,49 @@ using System.Linq.Expressions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Kyoo.Models;
+using Kyoo.Models.Exceptions;
using Microsoft.EntityFrameworkCore;
namespace Kyoo.Controllers
{
+ ///
+ /// A local repository to handle episodes.
+ ///
public class EpisodeRepository : LocalRepository, IEpisodeRepository
{
+ ///
+ /// Has this instance been disposed and should not handle requests?
+ ///
private bool _disposed;
+ ///
+ /// The databse handle
+ ///
private readonly DatabaseContext _database;
+ ///
+ /// A provider repository to handle externalID creation and deletion
+ ///
private readonly IProviderRepository _providers;
+ ///
+ /// A show repository to get show's slug from their ID and keep the slug in each episode.
+ ///
private readonly IShowRepository _shows;
+ ///
+ /// A track repository to handle creation and deletion of tracks related to the current episode.
+ ///
private readonly ITrackRepository _tracks;
+
+ ///
protected override Expression> DefaultSort => x => x.EpisodeNumber;
- public EpisodeRepository(DatabaseContext database,
+ ///
+ /// Create a new .
+ ///
+ /// The database handle to use.
+ /// A provider repository
+ /// A show repository
+ /// A track repository
+ public EpisodeRepository(DatabaseContext database,
IProviderRepository providers,
IShowRepository shows,
ITrackRepository tracks)
@@ -32,6 +60,7 @@ namespace Kyoo.Controllers
}
+ ///
public override void Dispose()
{
if (_disposed)
@@ -43,6 +72,7 @@ namespace Kyoo.Controllers
GC.SuppressFinalize(this);
}
+ ///
public override async ValueTask DisposeAsync()
{
if (_disposed)
@@ -53,7 +83,8 @@ namespace Kyoo.Controllers
await _shows.DisposeAsync();
}
- public override async Task Get(int id)
+ ///
+ public override async Task GetOrDefault(int id)
{
Episode ret = await base.Get(id);
if (ret != null)
@@ -61,13 +92,14 @@ namespace Kyoo.Controllers
return ret;
}
- public override async Task Get(string slug)
+ ///
+ public override async Task GetOrDefault(string slug)
{
Match match = Regex.Match(slug, @"(?.*)-s(?\d*)e(?\d*)");
if (match.Success)
{
- return await Get(match.Groups["show"].Value,
+ return await GetOrDefault(match.Groups["show"].Value,
int.Parse(match.Groups["season"].Value),
int.Parse(match.Groups["episode"].Value));
}
@@ -78,7 +110,8 @@ namespace Kyoo.Controllers
return episode;
}
- public override async Task Get(Expression> predicate)
+ ///
+ public override async Task GetOrDefault(Expression> predicate)
{
Episode ret = await base.Get(predicate);
if (ret != null)
@@ -86,7 +119,8 @@ namespace Kyoo.Controllers
return ret;
}
- public async Task Get(string showSlug, int seasonNumber, int episodeNumber)
+ ///
+ public async Task GetOrDefault(string showSlug, int seasonNumber, int episodeNumber)
{
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
&& x.SeasonNumber == seasonNumber
@@ -96,7 +130,26 @@ namespace Kyoo.Controllers
return ret;
}
+ ///
public async Task Get(int showID, int seasonNumber, int episodeNumber)
+ {
+ Episode ret = await GetOrDefault(showID, seasonNumber, episodeNumber);
+ if (ret == null)
+ throw new ItemNotFound($"No episode S{seasonNumber}E{episodeNumber} found on the show {showID}.");
+ return ret;
+ }
+
+ ///
+ public async Task Get(string showSlug, int seasonNumber, int episodeNumber)
+ {
+ Episode ret = await GetOrDefault(showSlug, seasonNumber, episodeNumber);
+ if (ret == null)
+ throw new ItemNotFound($"No episode S{seasonNumber}E{episodeNumber} found on the show {showSlug}.");
+ return ret;
+ }
+
+ ///
+ public async Task GetOrDefault(int showID, int seasonNumber, int episodeNumber)
{
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
&& x.SeasonNumber == seasonNumber
@@ -106,15 +159,7 @@ namespace Kyoo.Controllers
return ret;
}
- public async Task Get(int seasonID, int episodeNumber)
- {
- Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.SeasonID == seasonID
- && x.EpisodeNumber == episodeNumber);
- if (ret != null)
- ret.ShowSlug = await _shows.GetSlug(ret.ShowID);
- return ret;
- }
-
+ ///
public async Task GetAbsolute(int showID, int absoluteNumber)
{
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.ShowID == showID
@@ -124,6 +169,7 @@ namespace Kyoo.Controllers
return ret;
}
+ ///
public async Task GetAbsolute(string showSlug, int absoluteNumber)
{
Episode ret = await _database.Episodes.FirstOrDefaultAsync(x => x.Show.Slug == showSlug
@@ -133,6 +179,7 @@ namespace Kyoo.Controllers
return ret;
}
+ ///
public override async Task> Search(string query)
{
List episodes = await _database.Episodes
@@ -145,6 +192,7 @@ namespace Kyoo.Controllers
return episodes;
}
+ ///
public override async Task> GetAll(Expression> where = null,
Sort sort = default,
Pagination limit = default)
@@ -155,6 +203,7 @@ namespace Kyoo.Controllers
return episodes;
}
+ ///
public override async Task Create(Episode obj)
{
await base.Create(obj);
@@ -164,6 +213,7 @@ namespace Kyoo.Controllers
return await ValidateTracks(obj);
}
+ ///
protected override async Task EditRelations(Episode resource, Episode changed, bool resetOld)
{
if (resource.ShowID <= 0)
@@ -185,6 +235,11 @@ namespace Kyoo.Controllers
await Validate(resource);
}
+ ///
+ /// Set track's index and ensure that every tracks is well-formed.
+ ///
+ /// The resource to fix.
+ /// The parameter is returnned.
private async Task ValidateTracks(Episode resource)
{
resource.Tracks = await resource.Tracks.MapAsync((x, i) =>
@@ -199,6 +254,7 @@ namespace Kyoo.Controllers
return resource;
}
+ ///
protected override async Task Validate(Episode resource)
{
await base.Validate(resource);
@@ -211,6 +267,7 @@ namespace Kyoo.Controllers
}).ToListAsync();
}
+ ///
public override async Task Delete(Episode obj)
{
if (obj == null)
diff --git a/Kyoo/Controllers/Repositories/SeasonRepository.cs b/Kyoo/Controllers/Repositories/SeasonRepository.cs
index fb17d58f..22ee9a64 100644
--- a/Kyoo/Controllers/Repositories/SeasonRepository.cs
+++ b/Kyoo/Controllers/Repositories/SeasonRepository.cs
@@ -20,9 +20,21 @@ namespace Kyoo.Controllers
/// Has this instance been disposed and should not handle requests?
///
private bool _disposed;
+ ///
+ /// The database handle
+ ///
private readonly DatabaseContext _database;
+ ///
+ /// A provider repository to handle externalID creation and deletion
+ ///
private readonly IProviderRepository _providers;
+ ///
+ /// A show repository to get show's slug from their ID and keep the slug in each episode.
+ ///
private readonly IShowRepository _shows;
+ ///
+ /// A lazilly loaded episode repository to handle deletion of episodes with the season.
+ ///
private readonly Lazy _episodes;
///
diff --git a/Kyoo/Controllers/Repositories/ShowRepository.cs b/Kyoo/Controllers/Repositories/ShowRepository.cs
index f07e4f5a..e94419c2 100644
--- a/Kyoo/Controllers/Repositories/ShowRepository.cs
+++ b/Kyoo/Controllers/Repositories/ShowRepository.cs
@@ -9,18 +9,56 @@ using Microsoft.Extensions.DependencyInjection;
namespace Kyoo.Controllers
{
+ ///
+ /// A local repository to handle shows
+ ///
public class ShowRepository : LocalRepository, IShowRepository
{
+ ///
+ /// Has this instance been disposed and should not handle requests?
+ ///
private bool _disposed;
+ ///
+ /// The databse handle
+ ///
private readonly DatabaseContext _database;
+ ///
+ /// A studio repository to handle creation/validation of related studios.
+ ///
private readonly IStudioRepository _studios;
+ ///
+ /// A people repository to handle creation/validation of related people.
+ ///
private readonly IPeopleRepository _people;
+ ///
+ /// A genres repository to handle creation/validation of related genres.
+ ///
private readonly IGenreRepository _genres;
+ ///
+ /// A provider repository to handle externalID creation and deletion
+ ///
private readonly IProviderRepository _providers;
+ ///
+ /// A lazy loaded season repository to handle cascade deletion (seasons deletion whith it's show)
+ ///
private readonly Lazy _seasons;
+ ///
+ /// A lazy loaded episode repository to handle cascade deletion (episode deletion whith it's show)
+ ///
private readonly Lazy _episodes;
+
+ ///
protected override Expression> DefaultSort => x => x.Title;
+ ///
+ /// Create a new .
+ ///
+ /// The database handle to use
+ /// A studio repository
+ /// A people repository
+ /// A genres repository
+ /// A provider repository
+ /// A service provider to lazilly request a season and an episode repository
public ShowRepository(DatabaseContext database,
IStudioRepository studios,
IPeopleRepository people,
@@ -38,6 +76,7 @@ namespace Kyoo.Controllers
_episodes = new Lazy(services.GetRequiredService);
}
+ ///
public override void Dispose()
{
if (_disposed)
@@ -55,6 +94,7 @@ namespace Kyoo.Controllers
GC.SuppressFinalize(this);
}
+ ///
public override async ValueTask DisposeAsync()
{
if (_disposed)
@@ -71,6 +111,7 @@ namespace Kyoo.Controllers
await _episodes.Value.DisposeAsync();
}
+ ///
public override async Task> Search(string query)
{
query = $"%{query}%";
@@ -83,6 +124,7 @@ namespace Kyoo.Controllers
.ToListAsync();
}
+ ///
public override async Task Create(Show obj)
{
await base.Create(obj);
@@ -94,6 +136,7 @@ namespace Kyoo.Controllers
return obj;
}
+ ///
protected override async Task Validate(Show resource)
{
await base.Validate(resource);
@@ -119,6 +162,7 @@ namespace Kyoo.Controllers
});
}
+ ///
protected override async Task EditRelations(Show resource, Show changed, bool resetOld)
{
await Validate(changed);
@@ -145,6 +189,7 @@ namespace Kyoo.Controllers
}
}
+ ///
public async Task AddShowLink(int showID, int? libraryID, int? collectionID)
{
if (collectionID != null)
@@ -168,6 +213,7 @@ namespace Kyoo.Controllers
}
}
+ ///
public Task GetSlug(int showID)
{
return _database.Shows.Where(x => x.ID == showID)
@@ -175,6 +221,7 @@ namespace Kyoo.Controllers
.FirstOrDefaultAsync();
}
+ ///
public override async Task Delete(Show obj)
{
if (obj == null)