using ErsatzTV.Core.Domain; using ErsatzTV.Core.Interfaces.Repositories; using ErsatzTV.Core.Interfaces.Scheduling; using ErsatzTV.Core.Scheduling.YamlScheduling.Models; namespace ErsatzTV.Core.Scheduling.YamlScheduling; public class YamlPlayoutMarathonHelper(IMediaCollectionRepository mediaCollectionRepository) { public async Task> GetEnumerator( YamlPlayoutContentMarathonItem marathon, CollectionEnumeratorState state, CancellationToken cancellationToken) { if (!Enum.TryParse(marathon.ItemOrder, true, out PlaybackOrder playbackOrder)) { playbackOrder = PlaybackOrder.Shuffle; } var allMediaItems = new List(); // grab items from each show guid foreach (string showGuid in marathon.Guids.Map(g => $"{g.Source}://{g.Value}")) { allMediaItems.AddRange(await mediaCollectionRepository.GetShowItemsByShowGuids([showGuid])); } List> groups = []; // group by show if (string.Equals(marathon.GroupBy, "show", StringComparison.OrdinalIgnoreCase)) { groups.AddRange(allMediaItems.GroupBy(MediaItemKeyByShow)); } // group by season else if (string.Equals(marathon.GroupBy, "season", StringComparison.OrdinalIgnoreCase)) { groups.AddRange(allMediaItems.GroupBy(MediaItemKeyBySeason)); } Dictionary> itemMap = []; for (var index = 0; index < groups.Count; index++) { IGrouping group = groups[index]; PlaylistItem playlistItem = GroupToPlaylistItem(index, marathon, playbackOrder, group); itemMap.Add(playlistItem, group.ToList()); } return await PlaylistEnumerator.Create( mediaCollectionRepository, itemMap, state, cancellationToken); } private static GroupKey MediaItemKeyByShow(MediaItem mediaItem) => mediaItem switch { Episode e => new GroupKey( ProgramScheduleItemCollectionType.TelevisionShow, null, null, null, e.Season?.ShowId ?? 0), _ => new GroupKey(ProgramScheduleItemCollectionType.TelevisionShow, null, null, null, 0) }; private static GroupKey MediaItemKeyBySeason(MediaItem mediaItem) => mediaItem switch { Episode e => new GroupKey( ProgramScheduleItemCollectionType.TelevisionSeason, null, null, null, e.SeasonId), _ => new GroupKey(ProgramScheduleItemCollectionType.TelevisionSeason, null, null, null, 0) }; private static PlaylistItem GroupToPlaylistItem( int index, YamlPlayoutContentMarathonItem marathon, PlaybackOrder playbackOrder, IGrouping group) => new() { Index = index, CollectionType = group.Key.CollectionType, CollectionId = group.Key.CollectionId, MultiCollectionId = group.Key.MultiCollectionId, SmartCollectionId = group.Key.SmartCollectionId, MediaItemId = group.Key.MediaItemId, PlayAll = marathon.PlayAllItems, PlaybackOrder = playbackOrder, IncludeInProgramGuide = true }; private record GroupKey( ProgramScheduleItemCollectionType CollectionType, int? CollectionId, int? MultiCollectionId, int? SmartCollectionId, int? MediaItemId); }