mirror of https://github.com/ErsatzTV/ErsatzTV.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
134 lines
5.3 KiB
134 lines
5.3 KiB
using ErsatzTV.Core; |
|
using ErsatzTV.Core.Domain; |
|
using ErsatzTV.Infrastructure.Data; |
|
using ErsatzTV.Infrastructure.Extensions; |
|
using Microsoft.EntityFrameworkCore; |
|
|
|
namespace ErsatzTV.Application.MediaCollections; |
|
|
|
public class ReplacePlaylistItemsHandler(IDbContextFactory<TvContext> dbContextFactory) |
|
: IRequestHandler<ReplacePlaylistItems, Either<BaseError, List<PlaylistItemViewModel>>> |
|
{ |
|
public async Task<Either<BaseError, List<PlaylistItemViewModel>>> Handle( |
|
ReplacePlaylistItems request, |
|
CancellationToken cancellationToken) |
|
{ |
|
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken); |
|
Validation<BaseError, Playlist> validation = await Validate(dbContext, request); |
|
return await validation.Apply(ps => Persist(dbContext, request, ps)); |
|
} |
|
|
|
private static async Task<List<PlaylistItemViewModel>> Persist( |
|
TvContext dbContext, |
|
ReplacePlaylistItems request, |
|
Playlist playlist) |
|
{ |
|
playlist.Name = request.Name; |
|
//playlist.DateUpdated = DateTime.UtcNow; |
|
|
|
dbContext.RemoveRange(playlist.Items); |
|
playlist.Items = request.Items.Map(i => BuildItem(playlist, i.Index, i)).ToList(); |
|
|
|
await dbContext.SaveChangesAsync(); |
|
|
|
return playlist.Items.Map(Mapper.ProjectToViewModel).ToList(); |
|
} |
|
|
|
private static PlaylistItem BuildItem(Playlist playlist, int index, ReplacePlaylistItem item) => |
|
new() |
|
{ |
|
PlaylistId = playlist.Id, |
|
Index = index, |
|
CollectionType = item.CollectionType, |
|
CollectionId = item.CollectionId, |
|
MultiCollectionId = item.MultiCollectionId, |
|
SmartCollectionId = item.SmartCollectionId, |
|
MediaItemId = item.MediaItemId, |
|
PlaybackOrder = item.PlaybackOrder, |
|
PlayAll = item.PlayAll, |
|
IncludeInProgramGuide = item.IncludeInProgramGuide |
|
}; |
|
|
|
private static Task<Validation<BaseError, Playlist>> Validate(TvContext dbContext, ReplacePlaylistItems request) => |
|
PlaylistMustExist(dbContext, request.PlaylistId) |
|
.BindT(playlist => CollectionTypesMustBeValid(request, playlist)); |
|
|
|
private static Task<Validation<BaseError, Playlist>> PlaylistMustExist(TvContext dbContext, int playlistId) => |
|
dbContext.Playlists |
|
.Include(b => b.Items) |
|
.SelectOneAsync(b => b.Id, b => b.Id == playlistId) |
|
.Map(o => o.ToValidation<BaseError>("[PlaylistId] does not exist.")); |
|
|
|
private static Validation<BaseError, Playlist> CollectionTypesMustBeValid( |
|
ReplacePlaylistItems request, |
|
Playlist playlist) => |
|
request.Items.Map(item => CollectionTypeMustBeValid(item, playlist)).Sequence().Map(_ => playlist); |
|
|
|
private static Validation<BaseError, Playlist> CollectionTypeMustBeValid( |
|
ReplacePlaylistItem item, |
|
Playlist playlist) |
|
{ |
|
switch (item.CollectionType) |
|
{ |
|
case ProgramScheduleItemCollectionType.Collection: |
|
if (item.CollectionId is null) |
|
{ |
|
return BaseError.New("[Collection] is required for collection type 'Collection'"); |
|
} |
|
|
|
break; |
|
case ProgramScheduleItemCollectionType.TelevisionShow: |
|
if (item.MediaItemId is null) |
|
{ |
|
return BaseError.New("[MediaItem] is required for collection type 'TelevisionShow'"); |
|
} |
|
|
|
break; |
|
case ProgramScheduleItemCollectionType.TelevisionSeason: |
|
if (item.MediaItemId is null) |
|
{ |
|
return BaseError.New("[MediaItem] is required for collection type 'TelevisionSeason'"); |
|
} |
|
|
|
break; |
|
case ProgramScheduleItemCollectionType.Artist: |
|
if (item.MediaItemId is null) |
|
{ |
|
return BaseError.New("[MediaItem] is required for collection type 'Artist'"); |
|
} |
|
|
|
break; |
|
case ProgramScheduleItemCollectionType.MultiCollection: |
|
if (item.MultiCollectionId is null) |
|
{ |
|
return BaseError.New("[MultiCollection] is required for collection type 'MultiCollection'"); |
|
} |
|
|
|
break; |
|
case ProgramScheduleItemCollectionType.SmartCollection: |
|
if (item.SmartCollectionId is null) |
|
{ |
|
return BaseError.New("[SmartCollection] is required for collection type 'SmartCollection'"); |
|
} |
|
|
|
break; |
|
case ProgramScheduleItemCollectionType.Movie: |
|
case ProgramScheduleItemCollectionType.Episode: |
|
case ProgramScheduleItemCollectionType.MusicVideo: |
|
case ProgramScheduleItemCollectionType.OtherVideo: |
|
case ProgramScheduleItemCollectionType.Song: |
|
case ProgramScheduleItemCollectionType.Image: |
|
if (item.MediaItemId is null) |
|
{ |
|
return BaseError.New($"[MediaItem] is required for type '{item.CollectionType}'"); |
|
} |
|
|
|
break; |
|
case ProgramScheduleItemCollectionType.FakeCollection: |
|
default: |
|
return BaseError.New("[CollectionType] is invalid"); |
|
} |
|
|
|
return playlist; |
|
} |
|
}
|
|
|