mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Using nullables instead of -1
This commit is contained in:
parent
fdb6386462
commit
db5ae6f285
@ -16,6 +16,6 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
Task<Season> GetSeason(Show show, int seasonNumber);
|
Task<Season> GetSeason(Show show, int seasonNumber);
|
||||||
|
|
||||||
Task<Episode> GetEpisode(Show show, int seasonNumber, int episodeNumber, int absoluteNumber);
|
Task<Episode> GetEpisode(Show show, int? seasonNumber, int? episodeNumber, int? absoluteNumber);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ namespace Kyoo.Controllers
|
|||||||
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, int seasonNumber, Library library);
|
Task<Season> GetSeason(Show show, int seasonNumber, Library library);
|
||||||
Task<Episode> GetEpisode(Show show, string episodePath, int seasonNumber, int episodeNumber, int absoluteNumber, Library library);
|
Task<Episode> GetEpisode(Show show, string episodePath, int? seasonNumber, int? episodeNumber, int? absoluteNumber, Library library);
|
||||||
Task<ICollection<PeopleRole>> GetPeople(Show show, Library library);
|
Task<ICollection<PeopleRole>> GetPeople(Show show, Library library);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
@ -10,9 +9,8 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A class to represent a single show's episode.
|
/// A class to represent a single show's episode.
|
||||||
/// This is also used internally for movies (their number is juste set to -1).
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Episode : IResource, IOnMerge
|
public class Episode : IResource
|
||||||
{
|
{
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public int ID { get; set; }
|
public int ID { get; set; }
|
||||||
@ -31,6 +29,7 @@ namespace Kyoo.Models
|
|||||||
if (value == null)
|
if (value == null)
|
||||||
throw new ArgumentNullException(nameof(value));
|
throw new ArgumentNullException(nameof(value));
|
||||||
|
|
||||||
|
Console.WriteLine(value);
|
||||||
Match match = Regex.Match(value, @"(?<show>.+)-s(?<season>\d+)e(?<episode>\d+)");
|
Match match = Regex.Match(value, @"(?<show>.+)-s(?<season>\d+)e(?<episode>\d+)");
|
||||||
|
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
@ -44,13 +43,13 @@ namespace Kyoo.Models
|
|||||||
match = Regex.Match(value, @"(?<show>.*)-(?<absolute>\d*)");
|
match = Regex.Match(value, @"(?<show>.*)-(?<absolute>\d*)");
|
||||||
if (match.Success)
|
if (match.Success)
|
||||||
{
|
{
|
||||||
ShowSlug = match.Groups["Show"].Value;
|
ShowSlug = match.Groups["show"].Value;
|
||||||
AbsoluteNumber = int.Parse(match.Groups["absolute"].Value);
|
AbsoluteNumber = int.Parse(match.Groups["absolute"].Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ShowSlug = value;
|
ShowSlug = value;
|
||||||
SeasonNumber = -1;
|
SeasonNumber = null;
|
||||||
EpisodeNumber = -1;
|
EpisodeNumber = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,20 +81,17 @@ namespace Kyoo.Models
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The season in witch this episode is in.
|
/// The season in witch this episode is in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(-1)]
|
public int? SeasonNumber { get; set; }
|
||||||
public int SeasonNumber { get; set; } = -1;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of this episode is it's season.
|
/// The number of this episode is it's season.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(-1)]
|
public int? EpisodeNumber { get; set; }
|
||||||
public int EpisodeNumber { get; set; } = -1;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
|
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DefaultValue(-1)]
|
public int? AbsoluteNumber { get; set; }
|
||||||
public int AbsoluteNumber { get; set; } = -1;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The path of the video file for this episode. Any format supported by a <see cref="IFileManager"/> is allowed.
|
/// The path of the video file for this episode. Any format supported by a <see cref="IFileManager"/> is allowed.
|
||||||
@ -141,43 +137,31 @@ namespace Kyoo.Models
|
|||||||
/// <param name="showSlug">The slug of the show. It can't be null.</param>
|
/// <param name="showSlug">The slug of the show. It can't be null.</param>
|
||||||
/// <param name="seasonNumber">
|
/// <param name="seasonNumber">
|
||||||
/// The season in which the episode is.
|
/// The season in which the episode is.
|
||||||
/// If this is a movie or if the episode should be referred by it's absolute number, set this to -1.
|
/// If this is a movie or if the episode should be referred by it's absolute number, set this to null.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="episodeNumber">
|
/// <param name="episodeNumber">
|
||||||
/// The number of the episode in it's season.
|
/// The number of the episode in it's season.
|
||||||
/// If this is a movie or if the episode should be referred by it's absolute number, set this to -1.
|
/// If this is a movie or if the episode should be referred by it's absolute number, set this to null.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="absoluteNumber">
|
/// <param name="absoluteNumber">
|
||||||
/// The absolute number of this show.
|
/// The absolute number of this show.
|
||||||
/// If you don't know it or this is a movie, use -1
|
/// If you don't know it or this is a movie, use null
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>The slug corresponding to the given arguments</returns>
|
/// <returns>The slug corresponding to the given arguments</returns>
|
||||||
/// <exception cref="ArgumentNullException">The given show slug was null.</exception>
|
/// <exception cref="ArgumentNullException">The given show slug was null.</exception>
|
||||||
public static string GetSlug([NotNull] string showSlug,
|
public static string GetSlug([NotNull] string showSlug,
|
||||||
int seasonNumber = -1,
|
int? seasonNumber,
|
||||||
int episodeNumber = -1,
|
int? episodeNumber,
|
||||||
int absoluteNumber = -1)
|
int? absoluteNumber = null)
|
||||||
{
|
{
|
||||||
if (showSlug == null)
|
if (showSlug == null)
|
||||||
throw new ArgumentNullException(nameof(showSlug));
|
throw new ArgumentNullException(nameof(showSlug));
|
||||||
return seasonNumber switch
|
return seasonNumber switch
|
||||||
{
|
{
|
||||||
-1 when absoluteNumber == -1 => showSlug,
|
null when absoluteNumber == null => showSlug,
|
||||||
-1 => $"{showSlug}-{absoluteNumber}",
|
null => $"{showSlug}-{absoluteNumber}",
|
||||||
_ => $"{showSlug}-s{seasonNumber}e{episodeNumber}"
|
_ => $"{showSlug}-s{seasonNumber}e{episodeNumber}"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
|
||||||
public void OnMerge(object merged)
|
|
||||||
{
|
|
||||||
Episode other = (Episode)merged;
|
|
||||||
if (SeasonNumber == -1 && other.SeasonNumber != -1)
|
|
||||||
SeasonNumber = other.SeasonNumber;
|
|
||||||
if (EpisodeNumber == -1 && other.EpisodeNumber != -1)
|
|
||||||
EpisodeNumber = other.EpisodeNumber;
|
|
||||||
if (AbsoluteNumber == -1 && other.AbsoluteNumber != -1)
|
|
||||||
AbsoluteNumber = other.AbsoluteNumber;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,9 +50,9 @@ namespace Kyoo.Models
|
|||||||
[LoadableRelation(nameof(ShowID))] public Show Show { get; set; }
|
[LoadableRelation(nameof(ShowID))] public Show Show { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of this season. This can be set to 0 to indicate specials. This defaults to -1 for unset.
|
/// The number of this season. This can be set to 0 to indicate specials.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int SeasonNumber { get; set; } = -1;
|
public int SeasonNumber { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of this season.
|
/// The title of this season.
|
||||||
|
@ -118,7 +118,8 @@ namespace Kyoo.Models
|
|||||||
[LoadableRelation] public ICollection<Season> Seasons { get; set; }
|
[LoadableRelation] public ICollection<Season> Seasons { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The list of episodes in this show. If this is a movie, there will be a unique episode (with the seasonNumber and episodeNumber set to -1).
|
/// The list of episodes in this show.
|
||||||
|
/// If this is a movie, there will be a unique episode (with the seasonNumber and episodeNumber set to null).
|
||||||
/// Having an episode is necessary to store metadata and tracks.
|
/// Having an episode is necessary to store metadata and tracks.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[LoadableRelation] public ICollection<Episode> Episodes { get; set; }
|
[LoadableRelation] public ICollection<Episode> Episodes { get; set; }
|
||||||
|
@ -63,8 +63,8 @@ namespace Kyoo.Models
|
|||||||
}
|
}
|
||||||
|
|
||||||
EpisodeSlug = Episode.GetSlug(match.Groups["show"].Value,
|
EpisodeSlug = Episode.GetSlug(match.Groups["show"].Value,
|
||||||
match.Groups["season"].Success ? int.Parse(match.Groups["season"].Value) : -1,
|
match.Groups["season"].Success ? int.Parse(match.Groups["season"].Value) : null,
|
||||||
match.Groups["episode"].Success ? int.Parse(match.Groups["episode"].Value) : -1);
|
match.Groups["episode"].Success ? int.Parse(match.Groups["episode"].Value) : null);
|
||||||
Language = match.Groups["language"].Value;
|
Language = match.Groups["language"].Value;
|
||||||
IsForced = match.Groups["forced"].Success;
|
IsForced = match.Groups["forced"].Success;
|
||||||
if (match.Groups["type"].Success)
|
if (match.Groups["type"].Success)
|
||||||
|
@ -63,7 +63,7 @@ namespace Kyoo.Models
|
|||||||
public class WatchedEpisode : Link<User, Episode>
|
public class WatchedEpisode : Link<User, Episode>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Where the player has stopped watching the episode (-1 if not started, else between 0 and 100).
|
/// Where the player has stopped watching the episode (between 0 and 100).
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int WatchedPercentage { get; set; }
|
public int WatchedPercentage { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -37,20 +37,19 @@ namespace Kyoo.Models
|
|||||||
public string ShowSlug { get; set; }
|
public string ShowSlug { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The season in witch this episode is in. This defaults to -1 if not specified.
|
/// The season in witch this episode is in.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int SeasonNumber { get; set; }
|
public int? SeasonNumber { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The number of this episode is it's season. This defaults to -1 if not specified.
|
/// The number of this episode is it's season.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int EpisodeNumber { get; set; }
|
public int? EpisodeNumber { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
|
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
|
||||||
/// This defaults to -1 if not specified.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int AbsoluteNumber { get; set; }
|
public int? AbsoluteNumber { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The title of this episode.
|
/// The title of this episode.
|
||||||
@ -148,21 +147,30 @@ namespace Kyoo.Models
|
|||||||
await library.Load(ep, x => x.Show);
|
await library.Load(ep, x => x.Show);
|
||||||
await library.Load(ep, x => x.Tracks);
|
await library.Load(ep, x => x.Tracks);
|
||||||
|
|
||||||
if (!ep.Show.IsMovie)
|
if (!ep.Show.IsMovie && ep.SeasonNumber != null && ep.EpisodeNumber != null)
|
||||||
{
|
{
|
||||||
if (ep.EpisodeNumber > 1)
|
if (ep.EpisodeNumber > 1)
|
||||||
previous = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber - 1);
|
previous = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber.Value, ep.EpisodeNumber.Value - 1);
|
||||||
else if (ep.SeasonNumber > 1)
|
else if (ep.SeasonNumber > 1)
|
||||||
{
|
{
|
||||||
int count = await library.GetCount<Episode>(x => x.ShowID == ep.ShowID
|
previous = (await library.GetAll(x => x.ShowID == ep.ShowID
|
||||||
&& x.SeasonNumber == ep.SeasonNumber - 1);
|
&& x.SeasonNumber == ep.SeasonNumber.Value - 1,
|
||||||
previous = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber - 1, count);
|
limit: 1,
|
||||||
|
sort: new Sort<Episode>(x => x.EpisodeNumber, true))
|
||||||
|
).FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ep.EpisodeNumber >= await library.GetCount<Episode>(x => x.SeasonID == ep.SeasonID))
|
if (ep.EpisodeNumber >= await library.GetCount<Episode>(x => x.SeasonID == ep.SeasonID))
|
||||||
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber + 1, 1);
|
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber.Value + 1, 1);
|
||||||
else
|
else
|
||||||
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber + 1);
|
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber.Value, ep.EpisodeNumber.Value + 1);
|
||||||
|
}
|
||||||
|
else if (!ep.Show.IsMovie && ep.AbsoluteNumber != null)
|
||||||
|
{
|
||||||
|
previous = await library.GetOrDefault<Episode>(x => x.ShowID == ep.ShowID
|
||||||
|
&& x.AbsoluteNumber == ep.EpisodeNumber + 1);
|
||||||
|
next = await library.GetOrDefault<Episode>(x => x.ShowID == ep.ShowID
|
||||||
|
&& x.AbsoluteNumber == ep.AbsoluteNumber + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new WatchItem
|
return new WatchItem
|
||||||
|
@ -25,14 +25,25 @@ namespace Kyoo.SqLite.Migrations
|
|||||||
migrationBuilder.Sql(@"
|
migrationBuilder.Sql(@"
|
||||||
CREATE TRIGGER EpisodeSlugInsert AFTER INSERT ON Episodes FOR EACH ROW
|
CREATE TRIGGER EpisodeSlugInsert AFTER INSERT ON Episodes FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE Episodes SET Slug = (SELECT Slug from Shows WHERE ID = ShowID) || '-s' || SeasonNumber || 'e' || EpisodeNumber
|
UPDATE Episodes
|
||||||
|
SET Slug = (SELECT Slug from Shows WHERE ID = ShowID) ||
|
||||||
|
CASE (SeasonNumber)
|
||||||
|
WHEN NULL THEN '-' || AbsoluteNumber
|
||||||
|
ELSE '-s' || SeasonNumber || 'e' || EpisodeNumber
|
||||||
|
END
|
||||||
WHERE ID == new.ID;
|
WHERE ID == new.ID;
|
||||||
END");
|
END");
|
||||||
// language=SQLite
|
// language=SQLite
|
||||||
migrationBuilder.Sql(@"
|
migrationBuilder.Sql(@"
|
||||||
CREATE TRIGGER EpisodeSlugUpdate AFTER UPDATE OF EpisodeNumber, SeasonNumber, ShowID ON Episodes FOR EACH ROW
|
CREATE TRIGGER EpisodeSlugUpdate AFTER UPDATE OF AbsoluteNumber, EpisodeNumber, SeasonNumber, ShowID
|
||||||
|
ON Episodes FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE Episodes SET Slug = (SELECT Slug from Shows WHERE ID = ShowID) || '-s' || SeasonNumber || 'e' || EpisodeNumber
|
UPDATE Episodes
|
||||||
|
SET Slug = (SELECT Slug from Shows WHERE ID = ShowID) ||
|
||||||
|
CASE (SeasonNumber)
|
||||||
|
WHEN NULL THEN '-' || AbsoluteNumber
|
||||||
|
ELSE '-s' || SeasonNumber || 'e' || EpisodeNumber
|
||||||
|
END
|
||||||
WHERE ID == new.ID;
|
WHERE ID == new.ID;
|
||||||
END");
|
END");
|
||||||
|
|
||||||
@ -42,7 +53,13 @@ namespace Kyoo.SqLite.Migrations
|
|||||||
CREATE TRIGGER ShowSlugUpdate AFTER UPDATE OF Slug ON Shows FOR EACH ROW
|
CREATE TRIGGER ShowSlugUpdate AFTER UPDATE OF Slug ON Shows FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE Seasons SET Slug = new.Slug || '-s' || SeasonNumber WHERE ShowID = new.ID;
|
UPDATE Seasons SET Slug = new.Slug || '-s' || SeasonNumber WHERE ShowID = new.ID;
|
||||||
UPDATE Episodes SET Slug = new.Slug || '-s' || SeasonNumber || 'e' || EpisodeNumber WHERE ShowID = new.ID;
|
UPDATE Episodes
|
||||||
|
SET Slug = new.Slug ||
|
||||||
|
CASE (SeasonNumber)
|
||||||
|
WHEN NULL THEN '-' || AbsoluteNumber
|
||||||
|
ELSE '-s' || SeasonNumber || 'e' || EpisodeNumber
|
||||||
|
END
|
||||||
|
WHERE ShowID = new.ID;
|
||||||
END;");
|
END;");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +55,12 @@ namespace Kyoo.Tests.Library
|
|||||||
{
|
{
|
||||||
Episode episode = await _repository.Get(1);
|
Episode episode = await _repository.Get(1);
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e1", episode.Slug);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e1", episode.Slug);
|
||||||
await _repository.Edit(new Episode
|
episode = await _repository.Edit(new Episode
|
||||||
{
|
{
|
||||||
ID = 1,
|
ID = 1,
|
||||||
SeasonNumber = 2
|
SeasonNumber = 2
|
||||||
}, false);
|
}, false);
|
||||||
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s2e2", episode.Slug);
|
||||||
episode = await _repository.Get(1);
|
episode = await _repository.Get(1);
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s2e1", episode.Slug);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s2e1", episode.Slug);
|
||||||
}
|
}
|
||||||
@ -69,11 +70,12 @@ namespace Kyoo.Tests.Library
|
|||||||
{
|
{
|
||||||
Episode episode = await _repository.Get(1);
|
Episode episode = await _repository.Get(1);
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e1", episode.Slug);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e1", episode.Slug);
|
||||||
await _repository.Edit(new Episode
|
episode = await _repository.Edit(new Episode
|
||||||
{
|
{
|
||||||
ID = 1,
|
ID = 1,
|
||||||
EpisodeNumber = 2
|
EpisodeNumber = 2
|
||||||
}, false);
|
}, false);
|
||||||
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
||||||
episode = await _repository.Get(1);
|
episode = await _repository.Get(1);
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
||||||
}
|
}
|
||||||
@ -127,12 +129,13 @@ namespace Kyoo.Tests.Library
|
|||||||
public async Task AbsoluteNumberEditTest()
|
public async Task AbsoluteNumberEditTest()
|
||||||
{
|
{
|
||||||
await _repository.Create(TestSample.GetAbsoluteEpisode());
|
await _repository.Create(TestSample.GetAbsoluteEpisode());
|
||||||
await _repository.Edit(new Episode
|
Episode episode = await _repository.Edit(new Episode
|
||||||
{
|
{
|
||||||
ID = 1,
|
ID = 2,
|
||||||
AbsoluteNumber = 56
|
AbsoluteNumber = 56
|
||||||
}, false);
|
}, false);
|
||||||
Episode episode = await _repository.Get(2);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-56", episode.Slug);
|
||||||
|
episode = await _repository.Get(2);
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-56", episode.Slug);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-56", episode.Slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,27 +143,28 @@ namespace Kyoo.Tests.Library
|
|||||||
public async Task AbsoluteToNormalEditTest()
|
public async Task AbsoluteToNormalEditTest()
|
||||||
{
|
{
|
||||||
await _repository.Create(TestSample.GetAbsoluteEpisode());
|
await _repository.Create(TestSample.GetAbsoluteEpisode());
|
||||||
await _repository.Edit(new Episode
|
Episode episode = await _repository.Edit(new Episode
|
||||||
{
|
{
|
||||||
ID = 1,
|
ID = 2,
|
||||||
SeasonNumber = 1,
|
SeasonNumber = 1,
|
||||||
EpisodeNumber = 2
|
EpisodeNumber = 2
|
||||||
}, false);
|
}, false);
|
||||||
Episode episode = await _repository.Get(1);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
||||||
|
episode = await _repository.Get(2);
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-s1e2", episode.Slug);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
public async Task NormalToAbsoluteEditTest()
|
public async Task NormalToAbsoluteEditTest()
|
||||||
{
|
{
|
||||||
await _repository.Create(TestSample.GetAbsoluteEpisode());
|
Episode episode = await _repository.Edit(new Episode
|
||||||
await _repository.Edit(new Episode
|
|
||||||
{
|
{
|
||||||
ID = 1,
|
ID = 1,
|
||||||
SeasonNumber = -1,
|
SeasonNumber = null,
|
||||||
AbsoluteNumber = 12
|
AbsoluteNumber = 12
|
||||||
}, false);
|
}, false);
|
||||||
Episode episode = await _repository.Get(1);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-12", episode.Slug);
|
||||||
|
episode = await _repository.Get(1);
|
||||||
Assert.Equal($"{TestSample.Get<Show>().Slug}-12", episode.Slug);
|
Assert.Equal($"{TestSample.Get<Show>().Slug}-12", episode.Slug);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,9 +129,8 @@ namespace Kyoo.Tests
|
|||||||
ID = 2,
|
ID = 2,
|
||||||
ShowSlug = "anohana",
|
ShowSlug = "anohana",
|
||||||
ShowID = 1,
|
ShowID = 1,
|
||||||
SeasonID = -1,
|
SeasonNumber = null,
|
||||||
SeasonNumber = -1,
|
EpisodeNumber = null,
|
||||||
EpisodeNumber = -1,
|
|
||||||
AbsoluteNumber = 3,
|
AbsoluteNumber = 3,
|
||||||
Path = "/home/kyoo/anohana-3",
|
Path = "/home/kyoo/anohana-3",
|
||||||
Thumb = "thumbnail",
|
Thumb = "thumbnail",
|
||||||
|
@ -122,16 +122,15 @@ namespace Kyoo.Controllers
|
|||||||
season.Show = show;
|
season.Show = show;
|
||||||
season.ShowID = show.ID;
|
season.ShowID = show.ID;
|
||||||
season.ShowSlug = show.Slug;
|
season.ShowSlug = show.Slug;
|
||||||
season.SeasonNumber = season.SeasonNumber == -1 ? seasonNumber : season.SeasonNumber;
|
|
||||||
season.Title ??= $"Season {season.SeasonNumber}";
|
season.Title ??= $"Season {season.SeasonNumber}";
|
||||||
return season;
|
return season;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Episode> GetEpisode(Show show,
|
public async Task<Episode> GetEpisode(Show show,
|
||||||
string episodePath,
|
string episodePath,
|
||||||
int seasonNumber,
|
int? seasonNumber,
|
||||||
int episodeNumber,
|
int? episodeNumber,
|
||||||
int absoluteNumber,
|
int? absoluteNumber,
|
||||||
Library library)
|
Library library)
|
||||||
{
|
{
|
||||||
Episode episode = await GetMetadata(
|
Episode episode = await GetMetadata(
|
||||||
@ -142,9 +141,9 @@ namespace Kyoo.Controllers
|
|||||||
episode.ShowID = show.ID;
|
episode.ShowID = show.ID;
|
||||||
episode.ShowSlug = show.Slug;
|
episode.ShowSlug = show.Slug;
|
||||||
episode.Path = episodePath;
|
episode.Path = episodePath;
|
||||||
episode.SeasonNumber = episode.SeasonNumber != -1 ? episode.SeasonNumber : seasonNumber;
|
episode.SeasonNumber ??= seasonNumber;
|
||||||
episode.EpisodeNumber = episode.EpisodeNumber != -1 ? episode.EpisodeNumber : episodeNumber;
|
episode.EpisodeNumber ??= episodeNumber;
|
||||||
episode.AbsoluteNumber = episode.AbsoluteNumber != -1 ? episode.AbsoluteNumber : absoluteNumber;
|
episode.AbsoluteNumber ??= absoluteNumber;
|
||||||
return episode;
|
return episode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ namespace Kyoo.Controllers
|
|||||||
public override async Task<ICollection<Episode>> Search(string query)
|
public override async Task<ICollection<Episode>> Search(string query)
|
||||||
{
|
{
|
||||||
return await _database.Episodes
|
return await _database.Episodes
|
||||||
.Where(x => x.EpisodeNumber != -1)
|
.Where(x => x.EpisodeNumber != null)
|
||||||
.Where(_database.Like<Episode>(x => x.Title, $"%{query}%"))
|
.Where(_database.Like<Episode>(x => x.Title, $"%{query}%"))
|
||||||
.OrderBy(DefaultSort)
|
.OrderBy(DefaultSort)
|
||||||
.Take(20)
|
.Take(20)
|
||||||
|
@ -67,8 +67,8 @@ namespace Kyoo.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
string showSlug = match.Groups["show"].Value;
|
string showSlug = match.Groups["show"].Value;
|
||||||
int seasonNumber = match.Groups["season"].Success ? int.Parse(match.Groups["season"].Value) : -1;
|
int? seasonNumber = match.Groups["season"].Success ? int.Parse(match.Groups["season"].Value) : null;
|
||||||
int episodeNumber = match.Groups["episode"].Success ? int.Parse(match.Groups["episode"].Value) : -1;
|
int? episodeNumber = match.Groups["episode"].Success ? int.Parse(match.Groups["episode"].Value) : null;
|
||||||
string language = match.Groups["language"].Value;
|
string language = match.Groups["language"].Value;
|
||||||
bool forced = match.Groups["forced"].Success;
|
bool forced = match.Groups["forced"].Success;
|
||||||
if (match.Groups["type"].Success)
|
if (match.Groups["type"].Success)
|
||||||
|
@ -47,8 +47,8 @@ namespace Kyoo
|
|||||||
// TODO remove postgres from here and load it like a normal plugin.
|
// TODO remove postgres from here and load it like a normal plugin.
|
||||||
_plugins.LoadPlugins(new IPlugin[] {
|
_plugins.LoadPlugins(new IPlugin[] {
|
||||||
new CoreModule(configuration),
|
new CoreModule(configuration),
|
||||||
new PostgresModule(configuration, host),
|
// new PostgresModule(configuration, host),
|
||||||
// new SqLiteModule(configuration, host),
|
new SqLiteModule(configuration, host),
|
||||||
new AuthenticationModule(configuration, loggerFactory, host)
|
new AuthenticationModule(configuration, loggerFactory, host)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -210,18 +210,20 @@ namespace Kyoo.Tasks
|
|||||||
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["Show"].Value;
|
string showName = match.Groups["Show"].Value;
|
||||||
int seasonNumber = int.TryParse(match.Groups["Season"].Value, out int tmp) ? tmp : -1;
|
int? seasonNumber = int.TryParse(match.Groups["Season"].Value, out int tmp) ? tmp : null;
|
||||||
int episodeNumber = int.TryParse(match.Groups["Episode"].Value, out tmp) ? tmp : -1;
|
int? episodeNumber = int.TryParse(match.Groups["Episode"].Value, out tmp) ? tmp : null;
|
||||||
int absoluteNumber = int.TryParse(match.Groups["Absolute"].Value, out tmp) ? tmp : -1;
|
int? absoluteNumber = int.TryParse(match.Groups["Absolute"].Value, out tmp) ? tmp : null;
|
||||||
|
|
||||||
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 == null && episodeNumber == null && absoluteNumber == null;
|
||||||
Show show = await GetShow(libraryManager, showName, showPath, isMovie, library);
|
Show show = await GetShow(libraryManager, showName, showPath, isMovie, library);
|
||||||
if (isMovie)
|
if (isMovie)
|
||||||
await libraryManager!.Create(await GetMovie(show, path));
|
await libraryManager!.Create(await GetMovie(show, path));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Season season = await GetSeason(libraryManager, show, seasonNumber, library);
|
Season season = seasonNumber != null
|
||||||
|
? await GetSeason(libraryManager, show, seasonNumber.Value, library)
|
||||||
|
: null;
|
||||||
Episode episode = await GetEpisode(libraryManager,
|
Episode episode = await GetEpisode(libraryManager,
|
||||||
show,
|
show,
|
||||||
season,
|
season,
|
||||||
@ -315,8 +317,6 @@ namespace Kyoo.Tasks
|
|||||||
int seasonNumber,
|
int seasonNumber,
|
||||||
Library library)
|
Library library)
|
||||||
{
|
{
|
||||||
if (seasonNumber == -1)
|
|
||||||
return default;
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Season season = await libraryManager.Get(show.Slug, seasonNumber);
|
Season season = await libraryManager.Get(show.Slug, seasonNumber);
|
||||||
@ -343,21 +343,24 @@ namespace Kyoo.Tasks
|
|||||||
private async Task<Episode> GetEpisode(ILibraryManager libraryManager,
|
private async Task<Episode> GetEpisode(ILibraryManager libraryManager,
|
||||||
Show show,
|
Show show,
|
||||||
Season season,
|
Season season,
|
||||||
int episodeNumber,
|
int? episodeNumber,
|
||||||
int absoluteNumber,
|
int? absoluteNumber,
|
||||||
string episodePath,
|
string episodePath,
|
||||||
Library library)
|
Library library)
|
||||||
{
|
{
|
||||||
Episode episode = await MetadataProvider.GetEpisode(show,
|
Episode episode = await MetadataProvider.GetEpisode(show,
|
||||||
episodePath,
|
episodePath,
|
||||||
season?.SeasonNumber ?? -1,
|
season?.SeasonNumber,
|
||||||
episodeNumber,
|
episodeNumber,
|
||||||
absoluteNumber,
|
absoluteNumber,
|
||||||
library);
|
library);
|
||||||
|
|
||||||
season ??= await GetSeason(libraryManager, show, episode.SeasonNumber, library);
|
if (episode.SeasonNumber != null)
|
||||||
episode.Season = season;
|
{
|
||||||
episode.SeasonID = season?.ID;
|
season ??= await GetSeason(libraryManager, show, episode.SeasonNumber.Value, library);
|
||||||
|
episode.Season = season;
|
||||||
|
episode.SeasonID = season?.ID;
|
||||||
|
}
|
||||||
await ThumbnailsManager.Validate(episode);
|
await ThumbnailsManager.Validate(episode);
|
||||||
await GetTracks(episode);
|
await GetTracks(episode);
|
||||||
return episode;
|
return episode;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user