* rework television media * refactor poster saving * television and movie views are working again * remove dead code * use paper styling for all cards * add show poster, plot to seasons page * remove missing shows; cleanup interfaces * fix split show display (same show in different folders/sources) * add placeholder "add to schedule" button * no more duplicate television shows, even with the same show split across sources * stop releasing CLI for now * use season number as season placeholder * add television shows to collections * add television seasons to collections * add television episodes to collections * add movies to collections * remove movies, shows, seasons, episodes from collections * fix page width and menus * fix buffer size defaults * fix chronological episode ordering * allow deleting media collections * don't get stuck building a playout with an empty collection * schedule editing and playouts work again * minor cleanup * remove dead code * fix bugs with viewing movies as they are loading * add scanner tests; support nested movie folders * update collections docs * rearrange order of schedule items * add show and season to schedule * delete schedules that use legacy collections, reset all posters * move cleanup to new migration * load fallback metadata when nfo fails; don't require metadata in ui * update readme and screenshots
143 lines
5.8 KiB
C#
143 lines
5.8 KiB
C#
using System;
|
|
using System.Threading.Tasks;
|
|
using ErsatzTV.Core;
|
|
using ErsatzTV.Core.Domain;
|
|
using ErsatzTV.Core.Interfaces.Repositories;
|
|
using LanguageExt;
|
|
|
|
namespace ErsatzTV.Application.ProgramSchedules.Commands
|
|
{
|
|
public abstract class ProgramScheduleItemCommandBase
|
|
{
|
|
private readonly IProgramScheduleRepository _programScheduleRepository;
|
|
|
|
protected ProgramScheduleItemCommandBase(IProgramScheduleRepository programScheduleRepository) =>
|
|
_programScheduleRepository = programScheduleRepository;
|
|
|
|
protected async Task<Validation<BaseError, ProgramSchedule>> ProgramScheduleMustExist(int programScheduleId) =>
|
|
(await _programScheduleRepository.GetWithPlayouts(programScheduleId))
|
|
.ToValidation<BaseError>("[ProgramScheduleId] does not exist.");
|
|
|
|
protected Validation<BaseError, ProgramSchedule> PlayoutModeMustBeValid(
|
|
IProgramScheduleItemRequest item,
|
|
ProgramSchedule programSchedule)
|
|
{
|
|
switch (item.PlayoutMode)
|
|
{
|
|
case PlayoutMode.Flood:
|
|
case PlayoutMode.One:
|
|
break;
|
|
case PlayoutMode.Multiple:
|
|
if (item.MultipleCount.GetValueOrDefault() <= 0)
|
|
{
|
|
return BaseError.New("[MultipleCount] must be greater than 0 for playout mode 'multiple'");
|
|
}
|
|
|
|
break;
|
|
case PlayoutMode.Duration:
|
|
if (item.PlayoutDuration is null)
|
|
{
|
|
return BaseError.New("[PlayoutDuration] is required for playout mode 'duration'");
|
|
}
|
|
|
|
if (item.OfflineTail is null)
|
|
{
|
|
return BaseError.New("[OfflineTail] is required for playout mode 'duration'");
|
|
}
|
|
|
|
break;
|
|
default:
|
|
return BaseError.New("[PlayoutMode] is invalid");
|
|
}
|
|
|
|
return programSchedule;
|
|
}
|
|
|
|
protected Validation<BaseError, ProgramSchedule> CollectionTypeMustBeValid(
|
|
IProgramScheduleItemRequest item,
|
|
ProgramSchedule programSchedule)
|
|
{
|
|
switch (item.CollectionType)
|
|
{
|
|
case ProgramScheduleItemCollectionType.Collection:
|
|
if (item.MediaCollectionId is null)
|
|
{
|
|
return BaseError.New("[MediaCollection] is required for collection type 'Collection'");
|
|
}
|
|
|
|
break;
|
|
case ProgramScheduleItemCollectionType.TelevisionShow:
|
|
if (item.TelevisionShowId is null)
|
|
{
|
|
return BaseError.New("[TelevisionShow] is required for collection type 'TelevisionShow'");
|
|
}
|
|
|
|
break;
|
|
case ProgramScheduleItemCollectionType.TelevisionSeason:
|
|
if (item.TelevisionSeasonId is null)
|
|
{
|
|
return BaseError.New("[TelevisionSeason] is required for collection type 'TelevisionSeason'");
|
|
}
|
|
|
|
break;
|
|
default:
|
|
return BaseError.New("[CollectionType] is invalid");
|
|
}
|
|
|
|
return programSchedule;
|
|
}
|
|
|
|
protected ProgramScheduleItem BuildItem(
|
|
ProgramSchedule programSchedule,
|
|
int index,
|
|
IProgramScheduleItemRequest item) =>
|
|
item.PlayoutMode switch
|
|
{
|
|
PlayoutMode.Flood => new ProgramScheduleItemFlood
|
|
{
|
|
ProgramScheduleId = programSchedule.Id,
|
|
Index = index,
|
|
StartTime = item.StartTime,
|
|
CollectionType = item.CollectionType,
|
|
MediaCollectionId = item.MediaCollectionId,
|
|
TelevisionShowId = item.TelevisionShowId,
|
|
TelevisionSeasonId = item.TelevisionSeasonId
|
|
},
|
|
PlayoutMode.One => new ProgramScheduleItemOne
|
|
{
|
|
ProgramScheduleId = programSchedule.Id,
|
|
Index = index,
|
|
StartTime = item.StartTime,
|
|
CollectionType = item.CollectionType,
|
|
MediaCollectionId = item.MediaCollectionId,
|
|
TelevisionShowId = item.TelevisionShowId,
|
|
TelevisionSeasonId = item.TelevisionSeasonId
|
|
},
|
|
PlayoutMode.Multiple => new ProgramScheduleItemMultiple
|
|
{
|
|
ProgramScheduleId = programSchedule.Id,
|
|
Index = index,
|
|
StartTime = item.StartTime,
|
|
CollectionType = item.CollectionType,
|
|
MediaCollectionId = item.MediaCollectionId,
|
|
TelevisionShowId = item.TelevisionShowId,
|
|
TelevisionSeasonId = item.TelevisionSeasonId,
|
|
Count = item.MultipleCount.GetValueOrDefault()
|
|
},
|
|
PlayoutMode.Duration => new ProgramScheduleItemDuration
|
|
{
|
|
ProgramScheduleId = programSchedule.Id,
|
|
Index = index,
|
|
StartTime = item.StartTime,
|
|
CollectionType = item.CollectionType,
|
|
MediaCollectionId = item.MediaCollectionId,
|
|
TelevisionShowId = item.TelevisionShowId,
|
|
TelevisionSeasonId = item.TelevisionSeasonId,
|
|
PlayoutDuration = item.PlayoutDuration.GetValueOrDefault(),
|
|
OfflineTail = item.OfflineTail.GetValueOrDefault()
|
|
},
|
|
_ => throw new NotSupportedException($"Unsupported playout mode {item.PlayoutMode}")
|
|
};
|
|
}
|
|
}
|