From 767ee7ec51ee118e1d1b9f431eb3d9379d7013f7 Mon Sep 17 00:00:00 2001 From: Mikal Stordal Date: Thu, 30 Mar 2023 15:08:54 +0200 Subject: [PATCH] hotfix: fix up the series episode endpoint fix up the series episode endpoint to match the old default behaviour prior to ea90899 and 36ae037, while also including the new behaviour to let the user include everything, exclude everything, or only include the episodes that match the specified condidition. the current behaviour previous to this fixwas breaking both the v2 web ui and shokofin, while the new behaviour after this commit will not break them but still allow for more filtering. [no ci] [skip ci] --- .../API/v3/Controllers/TreeController.cs | 32 +++++++++++++++---- .../API/v3/Models/Common/IncludeOnlyFilter.cs | 25 +++++++++++++++ 2 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 Shoko.Server/API/v3/Models/Common/IncludeOnlyFilter.cs diff --git a/Shoko.Server/API/v3/Controllers/TreeController.cs b/Shoko.Server/API/v3/Controllers/TreeController.cs index d56d700bd..c66b3d5c2 100644 --- a/Shoko.Server/API/v3/Controllers/TreeController.cs +++ b/Shoko.Server/API/v3/Controllers/TreeController.cs @@ -542,9 +542,9 @@ public ActionResult GetMainSeriesInGroup([FromRoute] int groupID, [FromQ [HttpGet("Series/{seriesID}/Episode")] public ActionResult> GetEpisodes([FromRoute] int seriesID, [FromQuery] [Range(0, 1000)] int pageSize = 20, [FromQuery] [Range(1, int.MaxValue)] int page = 1, - [FromQuery] bool? includeMissing = null, [FromQuery] bool includeHidden = false, + [FromQuery] IncludeOnlyFilter includeMissing = IncludeOnlyFilter.False, [FromQuery] IncludeOnlyFilter includeHidden = IncludeOnlyFilter.False, [FromQuery, ModelBinder(typeof(CommaDelimitedModelBinder))] HashSet includeDataFrom = null, - [FromQuery] bool? includeWatched = null, [FromQuery] EpisodeType? type = null) + [FromQuery] IncludeOnlyFilter includeWatched = IncludeOnlyFilter.True, [FromQuery] EpisodeType? type = null) { var series = RepoFactory.AnimeSeries.GetByID(seriesID); if (series == null) @@ -557,20 +557,38 @@ [FromQuery] [Range(0, 1000)] int pageSize = 20, [FromQuery] [Range(1, int.MaxVal return Forbid(SeriesController.SeriesForbiddenForUser); } - return series.GetAnimeEpisodes(orderList: true, includeHidden: includeHidden) + return series.GetAnimeEpisodes(orderList: true, includeHidden: includeHidden != IncludeOnlyFilter.False) .Where(a => { + // Filter by hidden state, if spesified + if (includeHidden == IncludeOnlyFilter.Only && !a.IsHidden) + return false; + // Filter by episode type, if specified if (type.HasValue && type.Value != Episode.MapAniDBEpisodeType((AniDBEpisodeType)a.AniDB_Episode.EpisodeType)) return false; // Filter by availability, if specified - if (includeMissing.HasValue && includeMissing.Value == a.GetVideoLocals().Count > 0) - return false; + if (includeMissing != IncludeOnlyFilter.True) + { + // If we should hide missing episodes and the episode has no files, then hide it. + // Or if we should only show missing episodes and the episode has files, the hide it. + var shouldHideMissing = includeMissing == IncludeOnlyFilter.False; + var noFiles = a.GetVideoLocals().Count == 0; + if (shouldHideMissing == noFiles) + return false; + } // Filter by user watched status, if specified - if (includeWatched.HasValue && includeWatched.Value == (a.GetUserRecord(User.JMMUserID)?.WatchedDate != null)) - return false; + if (includeWatched != IncludeOnlyFilter.True) + { + // If we should hide watched episodes and the episode is watched, then hide it. + // Or if we should only show watched episodes and the the episode is not watched, then hide it. + var shouldHideWatched = includeWatched == IncludeOnlyFilter.False; + var isWatched = a.GetUserRecord(User.JMMUserID)?.WatchedDate != null; + if (shouldHideWatched == isWatched) + return false; + } return true; }) diff --git a/Shoko.Server/API/v3/Models/Common/IncludeOnlyFilter.cs b/Shoko.Server/API/v3/Models/Common/IncludeOnlyFilter.cs new file mode 100644 index 000000000..803b950b9 --- /dev/null +++ b/Shoko.Server/API/v3/Models/Common/IncludeOnlyFilter.cs @@ -0,0 +1,25 @@ + +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; + +namespace Shoko.Server.API.v3.Models.Common; + +[JsonConverter(typeof(StringEnumConverter), typeof(CamelCaseNamingStrategy))] +public enum IncludeOnlyFilter +{ + /// + /// Include nothing. + /// + False = 0, + + /// + /// Include everything. + /// + True = 1, + + /// + /// Include only the elements that fit the specified condition. + /// + Only = 2, +}