Skip to content

Commit

Permalink
feat: improved dashboard endpoint query parameters
Browse files Browse the repository at this point in the history
Made it possible to search for only restricted episodes/series in the APIv3 dashboard endpoints, and also made it possible to return a list of episodes for a given time-frame, and not just the `x` number of next days from today.
  • Loading branch information
revam committed Dec 25, 2024
1 parent f76efe8 commit 7c76681
Showing 1 changed file with 110 additions and 16 deletions.
126 changes: 110 additions & 16 deletions Shoko.Server/API/v3/Controllers/DashboardController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public Dashboard.SeriesSummary GetSeriesSummary()
public ListResult<Dashboard.EpisodeDetails> GetRecentlyAddedEpisodes(
[FromQuery, Range(0, 1000)] int pageSize = 30,
[FromQuery, Range(1, int.MaxValue)] int page = 1,
[FromQuery] bool includeRestricted = false
[FromQuery] IncludeOnlyFilter includeRestricted = IncludeOnlyFilter.False
)
{
var user = HttpContext.GetUser();
Expand All @@ -227,7 +227,21 @@ public Dashboard.SeriesSummary GetSeriesSummary()
var animeDict = seriesDict.Values
.ToDictionary(series => series.AnimeSeriesID, series => series.AniDB_Anime);
return episodeList
.Where(tuple => animeDict.TryGetValue(tuple.episode.AnimeSeriesID, out var anime) && (includeRestricted || !anime.IsRestricted))
.Where(tuple =>
{
if (!animeDict.TryGetValue(tuple.episode.AnimeSeriesID, out var anime))
return false;

if (includeRestricted is not IncludeOnlyFilter.True)
{
var onlyRestricted = includeRestricted is IncludeOnlyFilter.Only;
var isRestricted = anime.IsRestricted;
if (onlyRestricted != isRestricted)
return false;
}

return true;
})
.ToListResult(
tuple => GetEpisodeDetailsForSeriesAndEpisode(user, tuple.episode, seriesDict[tuple.episode.AnimeSeriesID], animeDict[tuple.episode.AnimeSeriesID], tuple.file),
page,
Expand All @@ -246,7 +260,7 @@ public Dashboard.SeriesSummary GetSeriesSummary()
public ListResult<Series> GetRecentlyAddedSeries(
[FromQuery, Range(0, 1000)] int pageSize = 20,
[FromQuery, Range(1, int.MaxValue)] int page = 1,
[FromQuery] bool includeRestricted = false
[FromQuery] IncludeOnlyFilter includeRestricted = IncludeOnlyFilter.False
)
{
var user = HttpContext.GetUser();
Expand All @@ -256,8 +270,21 @@ public ListResult<Series> GetRecentlyAddedSeries(
.SelectMany(file => file.AnimeEpisodes.Select(episode => episode.AnimeSeriesID))
.Distinct()
.Select(RepoFactory.AnimeSeries.GetByID)
.Where(series => series != null && user.AllowedSeries(series) &&
(includeRestricted || !series.AniDB_Anime.IsRestricted))
.Where(series =>
{
if (series?.AniDB_Anime is not { } anime || !user.AllowedAnime(anime))
return false;

if (includeRestricted is not IncludeOnlyFilter.True)
{
var onlyRestricted = includeRestricted is IncludeOnlyFilter.Only;
var isRestricted = anime.IsRestricted;
if (onlyRestricted != isRestricted)
return false;
}

return true;
})
.ToListResult(a => new Series(a, User.JMMUserID), page, pageSize);
}

Expand All @@ -276,16 +303,29 @@ public ListResult<Series> GetRecentlyAddedSeries(
[FromQuery, Range(0, int.MaxValue)] int page = 0,
[FromQuery] bool includeSpecials = true,
[FromQuery] bool includeOthers = false,
[FromQuery] bool includeRestricted = false
[FromQuery] IncludeOnlyFilter includeRestricted = IncludeOnlyFilter.False
)
{
var user = HttpContext.GetUser();
return RepoFactory.AnimeSeries_User.GetByUserID(user.JMMUserID)
.Where(record => record.LastEpisodeUpdate.HasValue)
.OrderByDescending(record => record.LastEpisodeUpdate)
.Select(record => RepoFactory.AnimeSeries.GetByID(record.AnimeSeriesID))
.Where(series => series is not null && user.AllowedSeries(series) &&
(includeRestricted || !series.AniDB_Anime.IsRestricted))
.Where(series =>
{
if (series?.AniDB_Anime is not { } anime || !user.AllowedAnime(anime))
return false;

if (includeRestricted is not IncludeOnlyFilter.True)
{
var onlyRestricted = includeRestricted is IncludeOnlyFilter.Only;
var isRestricted = anime.IsRestricted;
if (onlyRestricted != isRestricted)
return false;
}

return true;
})
.Select(series => (series, episode: _seriesService.GetActiveEpisode(series, user.JMMUserID, includeSpecials, includeOthers)))
.Where(tuple => tuple.episode != null)
.ToListResult(tuple => GetEpisodeDetailsForSeriesAndEpisode(user, tuple.episode, tuple.series), page, pageSize);
Expand All @@ -311,7 +351,7 @@ public ListResult<Series> GetRecentlyAddedSeries(
[FromQuery] bool onlyUnwatched = true,
[FromQuery] bool includeSpecials = true,
[FromQuery] bool includeOthers = false,
[FromQuery] bool includeRestricted = false,
[FromQuery] IncludeOnlyFilter includeRestricted = IncludeOnlyFilter.False,
[FromQuery] bool includeMissing = false,
[FromQuery] bool includeRewatching = false
)
Expand All @@ -322,8 +362,21 @@ public ListResult<Series> GetRecentlyAddedSeries(
record.LastEpisodeUpdate.HasValue && (!onlyUnwatched || record.UnwatchedEpisodeCount > 0))
.OrderByDescending(record => record.LastEpisodeUpdate)
.Select(record => RepoFactory.AnimeSeries.GetByID(record.AnimeSeriesID))
.Where(series => user.AllowedSeries(series) &&
(includeRestricted || !series.AniDB_Anime.IsRestricted))
.Where(series =>
{
if (series?.AniDB_Anime is not { } anime || !user.AllowedAnime(anime))
return false;

if (includeRestricted is not IncludeOnlyFilter.True)
{
var onlyRestricted = includeRestricted is IncludeOnlyFilter.Only;
var isRestricted = anime.IsRestricted;
if (onlyRestricted != isRestricted)
return false;
}

return true;
})
.Select(series => (series, episode: _seriesService.GetNextUpEpisode(
series,
user.JMMUserID,
Expand Down Expand Up @@ -375,9 +428,31 @@ public Dashboard.EpisodeDetails GetEpisodeDetailsForSeriesAndEpisode(SVR_JMMUser
[HttpGet("AniDBCalendar")]
public List<Dashboard.EpisodeDetails> GetAniDBCalendarInDays([FromQuery] int numberOfDays = 7,
[FromQuery] bool showAll = false, [FromQuery] bool includeRestricted = false)
=> GetCalendarEpisodes(
DateOnly.FromDateTime(DateTime.Today),
DateOnly.FromDateTime(DateTime.Today).AddDays(numberOfDays),
showAll ? IncludeOnlyFilter.True : IncludeOnlyFilter.False,
includeRestricted ? IncludeOnlyFilter.True : IncludeOnlyFilter.False
);

/// <summary>
/// Get the episodes within the given time-frame on the calendar.
/// </summary>
/// <param name="startDate">Start date.</param>
/// <param name="endDate">End date.</param>
/// <param name="includeMissing">Include missing episodes.</param>
/// <param name="includeRestricted">Include episodes from restricted (H) series.</param>
/// <returns></returns>
[HttpGet("CalendarEpisodes")]
public List<Dashboard.EpisodeDetails> GetCalendarEpisodes(
[FromQuery] DateOnly startDate = default,
[FromQuery] DateOnly endDate = default,
[FromQuery] IncludeOnlyFilter includeMissing = IncludeOnlyFilter.False,
[FromQuery] IncludeOnlyFilter includeRestricted = IncludeOnlyFilter.False
)
{
var user = HttpContext.GetUser();
var episodeList = RepoFactory.AniDB_Episode.GetForDate(DateTime.Today, DateTime.Today.AddDays(numberOfDays))
var episodeList = RepoFactory.AniDB_Episode.GetForDate(startDate.ToDateTime(TimeOnly.MinValue, DateTimeKind.Unspecified), endDate.ToDateTime(TimeOnly.MaxValue, DateTimeKind.Unspecified))
.ToList();
var animeDict = episodeList
.Select(episode => RepoFactory.AniDB_Anime.GetByAnimeID(episode.AnimeID))
Expand All @@ -389,10 +464,29 @@ public Dashboard.EpisodeDetails GetEpisodeDetailsForSeriesAndEpisode(SVR_JMMUser
.Distinct()
.ToDictionary(anime => anime.AniDB_ID);
return episodeList
.Where(episode => animeDict.TryGetValue(episode.AnimeID, out var anime) &&
user.AllowedAnime(anime) &&
(includeRestricted || !anime.IsRestricted) &&
(showAll || seriesDict.ContainsKey(episode.AnimeID)))
.Where(episode =>
{
if (!animeDict.TryGetValue(episode.AnimeID, out var anime) || !user.AllowedAnime(anime))
return false;

if (includeRestricted is not IncludeOnlyFilter.True)
{
var onlyRestricted = includeRestricted is IncludeOnlyFilter.Only;
var isRestricted = anime.IsRestricted;
if (onlyRestricted != isRestricted)
return false;
}

if (includeMissing is not IncludeOnlyFilter.True)
{
var shouldHideMissing = includeMissing is IncludeOnlyFilter.False;
var isMissing = !seriesDict.ContainsKey(episode.AnimeID);
if (shouldHideMissing == isMissing)
return false;
}

return true;
})
.OrderBy(episode => episode.GetAirDateAsDate())
.Select(episode =>
{
Expand Down

0 comments on commit 7c76681

Please sign in to comment.