From d61324a2f5bafabdb318bae7402d68471ce562fd Mon Sep 17 00:00:00 2001 From: Mikal Stordal Date: Tue, 21 Nov 2023 20:44:45 +0100 Subject: [PATCH] feat: add runtime length to webui series data --- Shoko.Server/API/v3/Helpers/WebUIFactory.cs | 30 ++++++++++++++++++++- Shoko.Server/API/v3/Models/Shoko/WebUI.cs | 6 +++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Shoko.Server/API/v3/Helpers/WebUIFactory.cs b/Shoko.Server/API/v3/Helpers/WebUIFactory.cs index 39e890e5d..f89e43ad2 100644 --- a/Shoko.Server/API/v3/Helpers/WebUIFactory.cs +++ b/Shoko.Server/API/v3/Helpers/WebUIFactory.cs @@ -1,5 +1,8 @@ using System; +using System.Collections.Generic; using System.Linq; +using Shoko.Models.Enums; +using Shoko.Models.Server; using Shoko.Server.API.v3.Models.Common; using Shoko.Server.Models; @@ -19,10 +22,13 @@ public WebUIFactory(FilterFactory filterFactory, SeriesFactory seriesFactory) public Models.Shoko.WebUI.WebUISeriesExtra GetWebUISeriesExtra(SVR_AnimeSeries series) { var anime = series.GetAnime(); + var animeEpisodes = anime.GetAniDBEpisodes(); + var runtimeLength = GuessCorrectRuntimeLength(animeEpisodes); var cast = _seriesFactory.GetCast(anime.AnimeID, new () { Role.CreatorRoleType.Studio, Role.CreatorRoleType.Producer }); var result = new Models.Shoko.WebUI.WebUISeriesExtra { + RuntimeLength = runtimeLength, FirstAirSeason = _filterFactory.GetFirstAiringSeasonGroupFilter(anime), Studios = cast.Where(role => role.RoleName == Role.CreatorRoleType.Studio).Select(role => role.Staff).ToList(), Producers = cast.Where(role => role.RoleName == Role.CreatorRoleType.Producer).Select(role => role.Staff).ToList(), @@ -30,7 +36,29 @@ public Models.Shoko.WebUI.WebUISeriesExtra GetWebUISeriesExtra(SVR_AnimeSeries s }; return result; } - + + private static TimeSpan? GuessCorrectRuntimeLength(IReadOnlyList episodes) + { + // Return early if empty. + if (episodes == null || episodes.Count == 0) + return null; + + // Filter the list and return if empty. + episodes = episodes + .Where(episode => episode.EpisodeType == (int)EpisodeType.Episode) + .ToList(); + if (episodes.Count == 0) + return null; + + // Get the runtime length of the only episode. + if (episodes.Count == 1) + return TimeSpan.FromSeconds(episodes[0].LengthSeconds); + + // Get the runtime length of the episode in the middle of the stack. + var index = (int)Math.Round(episodes.Count / 2d); + return TimeSpan.FromSeconds(episodes[index].LengthSeconds); + } + public Models.Shoko.WebUI.WebUIGroupExtra GetWebUIGroupExtra(SVR_AnimeGroup group, SVR_AnimeSeries series, SVR_AniDB_Anime anime, TagFilter.Filter filter = TagFilter.Filter.None, bool orderByName = false, int tagLimit = 30) { diff --git a/Shoko.Server/API/v3/Models/Shoko/WebUI.cs b/Shoko.Server/API/v3/Models/Shoko/WebUI.cs index 26d670b57..51c896cf8 100644 --- a/Shoko.Server/API/v3/Models/Shoko/WebUI.cs +++ b/Shoko.Server/API/v3/Models/Shoko/WebUI.cs @@ -133,6 +133,12 @@ public class WebUIGroupExtra public class WebUISeriesExtra { + /// + /// Common runtime length for the episodes, if the series have any + /// episodes. + /// + public TimeSpan? RuntimeLength { get; set; } + /// /// The first season this show was aired in. ///