Skip to content

Commit

Permalink
refactor: lay more groundwork for proper collection
Browse files Browse the repository at this point in the history
support.
  • Loading branch information
revam committed Mar 26, 2024
1 parent e0e2ae1 commit 4e7b5f7
Show file tree
Hide file tree
Showing 20 changed files with 473 additions and 708 deletions.
13 changes: 1 addition & 12 deletions Shokofin/API/Info/CollectionInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,7 @@ public class CollectionInfo

public IReadOnlyList<CollectionInfo> SubCollections;

public CollectionInfo(Group group)
{
Id = group.IDs.Shoko.ToString();
ParentId = group.IDs.ParentGroup?.ToString();
IsTopLevel = group.IDs.TopLevelGroup == group.IDs.Shoko;
Name = group.Name;
Shoko = group;
Shows = new List<ShowInfo>();
SubCollections = new List<CollectionInfo>();
}

public CollectionInfo(Group group, List<ShowInfo> shows, List<CollectionInfo> subCollections, Ordering.GroupFilterType filterByType)
public CollectionInfo(Group group, List<ShowInfo> shows, List<CollectionInfo> subCollections)
{
Id = group.IDs.Shoko.ToString();
ParentId = group.IDs.ParentGroup?.ToString();
Expand Down
3 changes: 3 additions & 0 deletions Shokofin/API/Info/SeasonInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ public class SeasonInfo

public Series.TvDB? TvDB;

public SeriesType Type;

public string[] Tags;

public string[] Genres;
Expand Down Expand Up @@ -145,6 +147,7 @@ public SeasonInfo(Series series, List<EpisodeInfo> episodes, List<Role> cast, Li
Shoko = series;
AniDB = series.AniDBEntity;
TvDB = series.TvDBEntityList.FirstOrDefault();
Type = series.AniDBEntity.Type;
Tags = tags;
Genres = genres;
Studios = studios;
Expand Down
168 changes: 107 additions & 61 deletions Shokofin/API/Info/ShowInfo.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Controller.Entities;
using Microsoft.Extensions.Logging;
using Shokofin.API.Models;
using Shokofin.Utils;
Expand All @@ -10,61 +12,109 @@ namespace Shokofin.API.Info;

public class ShowInfo
{
public string? Id;

public string? ParentId;

/// <summary>
/// Main Shoko Series Id.
/// </summary>
public string Id;

/// <summary>
/// Main Shoko Group Id.
/// </summary>
public string? GroupId;

/// <summary>
/// Shoko Group Id used for Collection Support.
/// </summary>
public string? CollectionId;

/// <summary>
/// The main name of the show.
/// </summary>
public string Name;

/// <summary>
/// Indicates this is a standalone show without a group attached to it.
/// </summary>
public bool IsStandalone =>
Shoko == null;

/// <summary>
/// The Shoko Group, if this is not a standalone show entry.
/// </summary>
public Group? Shoko;

/// <summary>
/// First premiere date of the show.
/// </summary>
public DateTime? PremiereDate =>
SeasonList
.Select(s => s.AniDB.AirDate)
.Where(s => s != null)
.OrderBy(s => s)
.FirstOrDefault();

/// <summary>
/// Ended date of the show.
/// </summary>
public DateTime? EndDate =>
SeasonList.Any(s => s.AniDB.EndDate == null) ? null : SeasonList
.Select(s => s.AniDB.AirDate)
.OrderBy(s => s)
.LastOrDefault();

/// <summary>
/// Overall content rating of the show.
/// </summary>
public string? ContentRating =>
DefaultSeason.AniDB.Restricted ? "XXX" : null;

/// <summary>
/// Overall community rating of the show.
/// </summary>
public float CommunityRating =>
(float)(SeasonList.Aggregate(0f, (total, seasonInfo) => total + seasonInfo.AniDB.Rating.ToFloat(10)) / SeasonList.Count);

/// <summary>
/// All tags from across all seasons.
/// </summary>
public string[] Tags;

/// <summary>
/// All genres from across all seasons.
/// </summary>
public string[] Genres;

/// <summary>
/// All studios from across all seasons.
/// </summary>
public string[] Studios;

/// <summary>
/// All staff from across all seasons.
/// </summary>
public PersonInfo[] Staff;

/// <summary>
/// All seasons.
/// </summary>
public List<SeasonInfo> SeasonList;

/// <summary>
/// The season order dictionary.
/// </summary>
public Dictionary<int, SeasonInfo> SeasonOrderDictionary;

/// <summary>
/// The season number base-number dictionary.
/// </summary>
public Dictionary<SeasonInfo, int> SeasonNumberBaseDictionary;

public SeasonInfo? DefaultSeason;

public ShowInfo(Series series)
{
Id = null;
ParentId = series.IDs.ParentGroup.ToString();
Name = series.Name;
Tags = System.Array.Empty<string>();
Genres = System.Array.Empty<string>();
Studios = System.Array.Empty<string>();
SeasonList = new();
SeasonNumberBaseDictionary = new();
SeasonOrderDictionary = new();
DefaultSeason = null;
}

public ShowInfo(Group group)
{
Id = group.IDs.Shoko.ToString();
Name = group.Name;
Shoko = group;
ParentId = group.IDs.ParentGroup?.ToString();
Tags = System.Array.Empty<string>();
Genres = System.Array.Empty<string>();
Studios = System.Array.Empty<string>();
SeasonList = new();
SeasonNumberBaseDictionary = new();
SeasonOrderDictionary = new();
DefaultSeason = null;
}
/// <summary>
/// The default season for the show.
/// </summary>
public SeasonInfo DefaultSeason;

public ShowInfo(SeasonInfo seasonInfo)
public ShowInfo(SeasonInfo seasonInfo, string? groupId = null)
{
var seasonNumberBaseDictionary = new Dictionary<SeasonInfo, int>() { { seasonInfo, 1 } };
var seasonOrderDictionary = new Dictionary<int, SeasonInfo>() { { 1, seasonInfo } };
Expand All @@ -74,41 +124,34 @@ public ShowInfo(SeasonInfo seasonInfo)
if (seasonInfo.OthersList.Count > 0)
seasonOrderDictionary.Add(++seasonNumberOffset, seasonInfo);

Id = null;
ParentId = seasonInfo.Shoko.IDs.ParentGroup.ToString();
Id = seasonInfo.Id;
GroupId = groupId ?? seasonInfo.Shoko.IDs.ParentGroup.ToString();
CollectionId = seasonInfo.Shoko.IDs.ParentGroup.ToString();
Name = seasonInfo.Shoko.Name;
Tags = seasonInfo.Tags;
Genres = seasonInfo.Genres;
Studios = seasonInfo.Studios;
Staff = seasonInfo.Staff;
SeasonList = new() { seasonInfo };
SeasonNumberBaseDictionary = seasonNumberBaseDictionary;
SeasonOrderDictionary = seasonOrderDictionary;
DefaultSeason = seasonInfo;
}

public ShowInfo(Group group, List<SeasonInfo> seriesList, Ordering.GroupFilterType filterByType, ILogger logger)
public ShowInfo(Group group, List<SeasonInfo> seasonList, ILogger logger, bool useGroupIdForCollection)
{
var groupId = group.IDs.Shoko.ToString();

if (seriesList.Count > 0) switch (filterByType) {
case Ordering.GroupFilterType.Movies:
seriesList = seriesList.Where(s => s.AniDB.Type == SeriesType.Movie).ToList();
break;
case Ordering.GroupFilterType.Others:
seriesList = seriesList.Where(s => s.AniDB.Type != SeriesType.Movie).ToList();
break;
}

// Order series list
var orderingType = filterByType == Ordering.GroupFilterType.Movies ? Plugin.Instance.Configuration.MovieOrdering : Plugin.Instance.Configuration.SeasonOrdering;
var orderingType = Plugin.Instance.Configuration.SeasonOrdering;
switch (orderingType) {
case Ordering.OrderType.Default:
break;
case Ordering.OrderType.ReleaseDate:
seriesList = seriesList.OrderBy(s => s?.AniDB?.AirDate ?? System.DateTime.MaxValue).ToList();
seasonList = seasonList.OrderBy(s => s?.AniDB?.AirDate ?? DateTime.MaxValue).ToList();
break;
case Ordering.OrderType.Chronological:
seriesList.Sort(new SeriesInfoRelationComparer());
seasonList.Sort(new SeriesInfoRelationComparer());
break;
}

Expand All @@ -121,22 +164,23 @@ public ShowInfo(Group group, List<SeasonInfo> seriesList, Ordering.GroupFilterTy
case Ordering.OrderType.Default:
case Ordering.OrderType.Chronological: {
int targetId = group.IDs.MainSeries;
foundIndex = seriesList.FindIndex(s => s.Shoko.IDs.Shoko == targetId);
foundIndex = seasonList.FindIndex(s => s.Shoko.IDs.Shoko == targetId);
break;
}
}

// Fallback to the first series if we can't get a base point for seasons.
if (foundIndex == -1)
{
logger.LogWarning("Unable to get a base-point for seasons within the group for the filter, so falling back to the first series in the group. This is most likely due to library separation being enabled. (Filter={FilterByType},Group={GroupID})", filterByType.ToString(), groupId);
logger.LogWarning("Unable to get a base-point for seasons within the group for the filter, so falling back to the first series in the group. This is most likely due to library separation being enabled. (Group={GroupID})", groupId);
foundIndex = 0;
}

var defaultSeason = seasonList[foundIndex];
var seasonOrderDictionary = new Dictionary<int, SeasonInfo>();
var seasonNumberBaseDictionary = new Dictionary<SeasonInfo, int>();
var seasonNumberOffset = 0;
foreach (var (seasonInfo, index) in seriesList.Select((s, i) => (s, i))) {
foreach (var (seasonInfo, index) in seasonList.Select((s, i) => (s, i))) {
seasonNumberBaseDictionary.Add(seasonInfo, ++seasonNumberOffset);
seasonOrderDictionary.Add(seasonNumberOffset, seasonInfo);
if (seasonInfo.AlternateEpisodesList.Count > 0)
Expand All @@ -145,17 +189,19 @@ public ShowInfo(Group group, List<SeasonInfo> seriesList, Ordering.GroupFilterTy
seasonOrderDictionary.Add(++seasonNumberOffset, seasonInfo);
}

Id = groupId;
Name = seriesList.Count > 0 ? seriesList[foundIndex].Shoko.Name : group.Name;
Id = defaultSeason.Id;
GroupId = groupId;
Name = group.Name;
Shoko = group;
ParentId = group.IDs.ParentGroup?.ToString();
Tags = seriesList.SelectMany(s => s.Tags).Distinct().ToArray();
Genres = seriesList.SelectMany(s => s.Genres).Distinct().ToArray();
Studios = seriesList.SelectMany(s => s.Studios).Distinct().ToArray();
SeasonList = seriesList;
CollectionId = useGroupIdForCollection ? groupId : group.IDs.ParentGroup?.ToString();
Tags = seasonList.SelectMany(s => s.Tags).Distinct().ToArray();
Genres = seasonList.SelectMany(s => s.Genres).Distinct().ToArray();
Studios = seasonList.SelectMany(s => s.Studios).Distinct().ToArray();
Staff = seasonList.SelectMany(s => s.Staff).DistinctBy(p => new { p.Type, p.Name, p.Role }).ToArray();
SeasonList = seasonList;
SeasonNumberBaseDictionary = seasonNumberBaseDictionary;
SeasonOrderDictionary = seasonOrderDictionary;
DefaultSeason = seriesList.Count > 0 ? seriesList[foundIndex] : null;
DefaultSeason = defaultSeason;
}

public SeasonInfo? GetSeriesInfoBySeasonNumber(int seasonNumber) {
Expand Down
4 changes: 2 additions & 2 deletions Shokofin/API/ShokoAPIClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ public Task<Series> GetSeriesFromEpisode(string id)
return Get<Series>($"/api/v3/Episode/{id}/Series?includeDataFrom=AniDB,TvDB");
}

public Task<List<Series>> GetSeriesInGroup(string groupID, int filterID = 0)
public Task<List<Series>> GetSeriesInGroup(string groupID, int filterID = 0, bool recursive = false)
{
return Get<List<Series>>($"/api/v3/Filter/{filterID}/Group/{groupID}/Series?recursive=false&includeMissing=true&includeIgnored=false&includeDataFrom=AniDB,TvDB");
return Get<List<Series>>($"/api/v3/Filter/{filterID}/Group/{groupID}/Series?recursive={recursive}&includeMissing=true&includeIgnored=false&includeDataFrom=AniDB,TvDB");
}

public Task<List<Role>> GetSeriesCast(string id)
Expand Down
Loading

0 comments on commit 4e7b5f7

Please sign in to comment.