mirror of https://github.com/ErsatzTV/ErsatzTV.git
Browse Source
* refactor create playout handler * refactor get all playouts handler * refactor delete playout handler * remove dead code * ignore unnamed artists for collections * more repository cleanup * more schedule items refactoring * more playout refactoring * refactor playout builder * refactor ffmpeg profiles * more ffmpeg profile refactoring * rework resolutions * refactor media collections * refactor config elements * update changelog * more cleanuppull/259/head
208 changed files with 1515 additions and 16917 deletions
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.Channels.Commands |
||||
{ |
||||
public record CreateChannelResult(int ChannelId) : EntityIdResult(ChannelId); |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application |
||||
{ |
||||
public record EntityIdResult(int Id); |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.FFmpegProfiles.Commands |
||||
{ |
||||
public record CreateFFmpegProfileResult(int FFmpegProfileId) : EntityIdResult(FFmpegProfileId); |
||||
} |
||||
@ -1,9 +1,7 @@
@@ -1,9 +1,7 @@
|
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.FFmpegProfiles.Commands |
||||
{ |
||||
public record DeleteFFmpegProfile(int FFmpegProfileId) : IRequest<Either<BaseError, Task>>; |
||||
public record DeleteFFmpegProfile(int FFmpegProfileId) : MediatR.IRequest<Either<BaseError, Unit>>; |
||||
} |
||||
|
||||
@ -1,32 +1,43 @@
@@ -1,32 +1,43 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace ErsatzTV.Application.FFmpegProfiles.Commands |
||||
{ |
||||
public class DeleteFFmpegProfileHandler : IRequestHandler<DeleteFFmpegProfile, Either<BaseError, Task>> |
||||
public class DeleteFFmpegProfileHandler : IRequestHandler<DeleteFFmpegProfile, Either<BaseError, LanguageExt.Unit>> |
||||
{ |
||||
private readonly IFFmpegProfileRepository _ffmpegProfileRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public DeleteFFmpegProfileHandler(IFFmpegProfileRepository ffmpegProfileRepository) => |
||||
_ffmpegProfileRepository = ffmpegProfileRepository; |
||||
public DeleteFFmpegProfileHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public async Task<Either<BaseError, Task>> Handle( |
||||
public async Task<Either<BaseError, LanguageExt.Unit>> Handle( |
||||
DeleteFFmpegProfile request, |
||||
CancellationToken cancellationToken) => |
||||
(await FFmpegProfileMustExist(request)) |
||||
.Map(DoDeletion) |
||||
.ToEither<Task>(); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
Validation<BaseError, FFmpegProfile> validation = await FFmpegProfileMustExist(dbContext, request); |
||||
return await validation.Apply(p => DoDeletion(dbContext, p)); |
||||
} |
||||
|
||||
private Task DoDeletion(int channelId) => _ffmpegProfileRepository.Delete(channelId); |
||||
private static async Task<LanguageExt.Unit> DoDeletion(TvContext dbContext, FFmpegProfile ffmpegProfile) |
||||
{ |
||||
dbContext.FFmpegProfiles.Remove(ffmpegProfile); |
||||
await dbContext.SaveChangesAsync(); |
||||
return LanguageExt.Unit.Default; |
||||
} |
||||
|
||||
private async Task<Validation<BaseError, int>> FFmpegProfileMustExist( |
||||
DeleteFFmpegProfile deleteFFmpegProfile) => |
||||
(await _ffmpegProfileRepository.Get(deleteFFmpegProfile.FFmpegProfileId)) |
||||
.ToValidation<BaseError>($"FFmpegProfile {deleteFFmpegProfile.FFmpegProfileId} does not exist.") |
||||
.Map(c => c.Id); |
||||
private static Task<Validation<BaseError, FFmpegProfile>> FFmpegProfileMustExist( |
||||
TvContext dbContext, |
||||
DeleteFFmpegProfile request) => |
||||
dbContext.FFmpegProfiles |
||||
.SelectOneAsync(p => p.Id, p => p.Id == request.FFmpegProfileId) |
||||
.Map(o => o.ToValidation<BaseError>($"FFmpegProfile {request.FFmpegProfileId} does not exist")); |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.FFmpegProfiles.Commands |
||||
{ |
||||
public record UpdateFFmpegProfileResult(int FFmpegProfileId) : EntityIdResult(FFmpegProfileId); |
||||
} |
||||
@ -1,23 +1,30 @@
@@ -1,23 +1,30 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using static ErsatzTV.Application.FFmpegProfiles.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.FFmpegProfiles.Queries |
||||
{ |
||||
public class GetFFmpegProfileByIdHandler : IRequestHandler<GetFFmpegProfileById, Option<FFmpegProfileViewModel>> |
||||
{ |
||||
private readonly IFFmpegProfileRepository _ffmpegProfileRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public GetFFmpegProfileByIdHandler(IFFmpegProfileRepository ffmpegProfileRepository) => |
||||
_ffmpegProfileRepository = ffmpegProfileRepository; |
||||
public GetFFmpegProfileByIdHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public Task<Option<FFmpegProfileViewModel>> Handle( |
||||
public async Task<Option<FFmpegProfileViewModel>> Handle( |
||||
GetFFmpegProfileById request, |
||||
CancellationToken cancellationToken) => |
||||
_ffmpegProfileRepository.Get(request.Id) |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
return await dbContext.FFmpegProfiles |
||||
.Include(p => p.Resolution) |
||||
.SelectOneAsync(p => p.Id, p => p.Id == request.Id) |
||||
.MapT(ProjectToViewModel); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,9 +1,8 @@
@@ -1,9 +1,8 @@
|
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaCollections.Commands |
||||
{ |
||||
public record DeleteCollection(int CollectionId) : IRequest<Either<BaseError, Task>>; |
||||
public record DeleteCollection(int CollectionId) : IRequest<Either<BaseError, LanguageExt.Unit>>; |
||||
} |
||||
|
||||
@ -1,33 +1,42 @@
@@ -1,33 +1,42 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace ErsatzTV.Application.MediaCollections.Commands |
||||
{ |
||||
public class DeleteCollectionHandler : IRequestHandler<DeleteCollection, Either<BaseError, Task>> |
||||
public class DeleteCollectionHandler : MediatR.IRequestHandler<DeleteCollection, Either<BaseError, Unit>> |
||||
{ |
||||
private readonly IMediaCollectionRepository _mediaCollectionRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public DeleteCollectionHandler(IMediaCollectionRepository mediaCollectionRepository) => |
||||
_mediaCollectionRepository = mediaCollectionRepository; |
||||
public DeleteCollectionHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public async Task<Either<BaseError, Task>> Handle( |
||||
public async Task<Either<BaseError, Unit>> Handle( |
||||
DeleteCollection request, |
||||
CancellationToken cancellationToken) => |
||||
(await CollectionMustExist(request)) |
||||
.Map(DoDeletion) |
||||
.ToEither<Task>(); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
|
||||
private Task DoDeletion(int mediaCollectionId) => _mediaCollectionRepository.Delete(mediaCollectionId); |
||||
Validation<BaseError, Collection> validation = await CollectionMustExist(dbContext, request); |
||||
return await validation.Apply(c => DoDeletion(dbContext, c)); |
||||
} |
||||
|
||||
private async Task<Validation<BaseError, int>> CollectionMustExist( |
||||
DeleteCollection deleteMediaCollection) => |
||||
(await _mediaCollectionRepository.Get(deleteMediaCollection.CollectionId)) |
||||
.ToValidation<BaseError>( |
||||
$"Collection {deleteMediaCollection.CollectionId} does not exist.") |
||||
.Map(c => c.Id); |
||||
private static Task<Unit> DoDeletion(TvContext dbContext, Collection collection) |
||||
{ |
||||
dbContext.Collections.Remove(collection); |
||||
return dbContext.SaveChangesAsync().ToUnit(); |
||||
} |
||||
|
||||
private static Task<Validation<BaseError, Collection>> CollectionMustExist( |
||||
TvContext dbContext, |
||||
DeleteCollection request) => |
||||
dbContext.Collections |
||||
.SelectOneAsync(c => c.Id, c => c.Id == request.CollectionId) |
||||
.Map(o => o.ToValidation<BaseError>($"Collection {request.CollectionId} does not exist.")); |
||||
} |
||||
} |
||||
|
||||
@ -1,25 +1,30 @@
@@ -1,25 +1,30 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using static ErsatzTV.Application.MediaCollections.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaCollections.Queries |
||||
{ |
||||
public class |
||||
GetCollectionByIdHandler : IRequestHandler<GetCollectionById, |
||||
Option<MediaCollectionViewModel>> |
||||
public class GetCollectionByIdHandler : |
||||
IRequestHandler<GetCollectionById, Option<MediaCollectionViewModel>> |
||||
{ |
||||
private readonly IMediaCollectionRepository _mediaCollectionRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public GetCollectionByIdHandler(IMediaCollectionRepository mediaCollectionRepository) => |
||||
_mediaCollectionRepository = mediaCollectionRepository; |
||||
public GetCollectionByIdHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public Task<Option<MediaCollectionViewModel>> Handle( |
||||
public async Task<Option<MediaCollectionViewModel>> Handle( |
||||
GetCollectionById request, |
||||
CancellationToken cancellationToken) => |
||||
_mediaCollectionRepository.Get(request.Id) |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
return await dbContext.Collections |
||||
.SelectOneAsync(c => c.Id, c => c.Id == request.Id) |
||||
.MapT(ProjectToViewModel); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,9 +0,0 @@
@@ -1,9 +0,0 @@
|
||||
using System.Collections.Generic; |
||||
using ErsatzTV.Application.MediaItems; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaCollections.Queries |
||||
{ |
||||
public record GetCollectionItems(int Id) : IRequest<Option<IEnumerable<MediaItemViewModel>>>; |
||||
} |
||||
@ -1,26 +0,0 @@
@@ -1,26 +0,0 @@
|
||||
using System.Collections.Generic; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Application.MediaItems; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaItems.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaCollections.Queries |
||||
{ |
||||
public class GetCollectionItemsHandler : IRequestHandler<GetCollectionItems, |
||||
Option<IEnumerable<MediaItemViewModel>>> |
||||
{ |
||||
private readonly IMediaCollectionRepository _mediaCollectionRepository; |
||||
|
||||
public GetCollectionItemsHandler(IMediaCollectionRepository mediaCollectionRepository) => |
||||
_mediaCollectionRepository = mediaCollectionRepository; |
||||
|
||||
public Task<Option<IEnumerable<MediaItemViewModel>>> Handle( |
||||
GetCollectionItems request, |
||||
CancellationToken cancellationToken) => |
||||
_mediaCollectionRepository.GetItems(request.Id) |
||||
.MapT(mediaItems => mediaItems.Map(ProjectToViewModel)); |
||||
} |
||||
} |
||||
@ -1,9 +0,0 @@
@@ -1,9 +0,0 @@
|
||||
namespace ErsatzTV.Application.MediaItems |
||||
{ |
||||
public record MediaItemSearchResultViewModel( |
||||
int Id, |
||||
string Source, |
||||
string MediaType, |
||||
string Title, |
||||
string Duration); |
||||
} |
||||
@ -1,4 +0,0 @@
@@ -1,4 +0,0 @@
|
||||
namespace ErsatzTV.Application.MediaItems |
||||
{ |
||||
public record MediaItemViewModel(int Id, int LibraryPathId); |
||||
} |
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
using System.Collections.Generic; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems.Queries |
||||
{ |
||||
public record GetAllMediaItems : IRequest<List<MediaItemViewModel>>; |
||||
} |
||||
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaItems.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems.Queries |
||||
{ |
||||
public class GetAllMediaItemsHandler : IRequestHandler<GetAllMediaItems, List<MediaItemViewModel>> |
||||
{ |
||||
private readonly IMediaItemRepository _mediaItemRepository; |
||||
|
||||
public GetAllMediaItemsHandler(IMediaItemRepository mediaItemRepository) => |
||||
_mediaItemRepository = mediaItemRepository; |
||||
|
||||
public Task<List<MediaItemViewModel>> Handle( |
||||
GetAllMediaItems request, |
||||
CancellationToken cancellationToken) => |
||||
_mediaItemRepository.GetAll().Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
} |
||||
} |
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems.Queries |
||||
{ |
||||
public record GetMediaItemById(int Id) : IRequest<Option<MediaItemViewModel>>; |
||||
} |
||||
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaItems.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaItems.Queries |
||||
{ |
||||
public class GetMediaItemByIdHandler : IRequestHandler<GetMediaItemById, Option<MediaItemViewModel>> |
||||
{ |
||||
private readonly IMediaItemRepository _mediaItemRepository; |
||||
|
||||
public GetMediaItemByIdHandler(IMediaItemRepository mediaItemRepository) => |
||||
_mediaItemRepository = mediaItemRepository; |
||||
|
||||
public Task<Option<MediaItemViewModel>> Handle( |
||||
GetMediaItemById request, |
||||
CancellationToken cancellationToken) => |
||||
_mediaItemRepository.Get(request.Id) |
||||
.MapT(ProjectToViewModel); |
||||
} |
||||
} |
||||
@ -1,16 +0,0 @@
@@ -1,16 +0,0 @@
|
||||
using System; |
||||
using ErsatzTV.Core.Domain; |
||||
|
||||
namespace ErsatzTV.Application.MediaSources |
||||
{ |
||||
internal static class Mapper |
||||
{ |
||||
internal static MediaSourceViewModel ProjectToViewModel(MediaSource mediaSource) => |
||||
mediaSource switch |
||||
{ |
||||
LocalMediaSource lms => new LocalMediaSourceViewModel(lms.Id), |
||||
PlexMediaSource pms => Plex.Mapper.ProjectToViewModel(pms), |
||||
_ => throw new NotSupportedException($"Unsupported media source {mediaSource.GetType().Name}") |
||||
}; |
||||
} |
||||
} |
||||
@ -1,6 +0,0 @@
@@ -1,6 +0,0 @@
|
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaSources.Queries |
||||
{ |
||||
public record CountMediaItemsById(int MediaSourceId) : IRequest<int>; |
||||
} |
||||
@ -1,18 +0,0 @@
@@ -1,18 +0,0 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaSources.Queries |
||||
{ |
||||
public class CountMediaItemsByIdHandler : IRequestHandler<CountMediaItemsById, int> |
||||
{ |
||||
private readonly IMediaSourceRepository _mediaSourceRepository; |
||||
|
||||
public CountMediaItemsByIdHandler(IMediaSourceRepository mediaSourceRepository) => |
||||
_mediaSourceRepository = mediaSourceRepository; |
||||
|
||||
public Task<int> Handle(CountMediaItemsById request, CancellationToken cancellationToken) => |
||||
_mediaSourceRepository.CountMediaItems(request.MediaSourceId); |
||||
} |
||||
} |
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
using System.Collections.Generic; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaSources.Queries |
||||
{ |
||||
public record GetAllMediaSources : IRequest<List<MediaSourceViewModel>>; |
||||
} |
||||
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaSources.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaSources.Queries |
||||
{ |
||||
public class GetAllMediaSourcesHandler : IRequestHandler<GetAllMediaSources, List<MediaSourceViewModel>> |
||||
{ |
||||
private readonly IMediaSourceRepository _mediaSourceRepository; |
||||
|
||||
public GetAllMediaSourcesHandler(IMediaSourceRepository mediaSourceRepository) => |
||||
_mediaSourceRepository = mediaSourceRepository; |
||||
|
||||
public async Task<List<MediaSourceViewModel>> Handle( |
||||
GetAllMediaSources request, |
||||
CancellationToken cancellationToken) => |
||||
(await _mediaSourceRepository.GetAll()).Map(ProjectToViewModel).ToList(); |
||||
} |
||||
} |
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.MediaSources.Queries |
||||
{ |
||||
public record GetMediaSourceById(int Id) : IRequest<Option<MediaSourceViewModel>>; |
||||
} |
||||
@ -1,23 +0,0 @@
@@ -1,23 +0,0 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.MediaSources.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.MediaSources.Queries |
||||
{ |
||||
public class GetMediaSourceByIdHandler : IRequestHandler<GetMediaSourceById, Option<MediaSourceViewModel>> |
||||
{ |
||||
private readonly IMediaSourceRepository _mediaSourceRepository; |
||||
|
||||
public GetMediaSourceByIdHandler(IMediaSourceRepository mediaSourceRepository) => |
||||
_mediaSourceRepository = mediaSourceRepository; |
||||
|
||||
public Task<Option<MediaSourceViewModel>> Handle( |
||||
GetMediaSourceById request, |
||||
CancellationToken cancellationToken) => |
||||
_mediaSourceRepository.Get(request.Id) |
||||
.MapT(ProjectToViewModel); |
||||
} |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.Playouts.Commands |
||||
{ |
||||
public record CreatePlayoutResponse(int PlayoutId); |
||||
} |
||||
@ -1,9 +1,9 @@
@@ -1,9 +1,9 @@
|
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Unit = LanguageExt.Unit; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Commands |
||||
{ |
||||
public record DeletePlayout(int PlayoutId) : IRequest<Either<BaseError, Task>>; |
||||
public record DeletePlayout(int PlayoutId) : IRequest<Either<BaseError, Unit>>; |
||||
} |
||||
|
||||
@ -1,32 +1,42 @@
@@ -1,32 +1,42 @@
|
||||
using System.Threading; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Unit = LanguageExt.Unit; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Commands |
||||
{ |
||||
public class DeletePlayoutHandler : IRequestHandler<DeletePlayout, Either<BaseError, Task>> |
||||
public class DeletePlayoutHandler : IRequestHandler<DeletePlayout, Either<BaseError, Unit>> |
||||
{ |
||||
private readonly IPlayoutRepository _playoutRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public DeletePlayoutHandler(IPlayoutRepository playoutRepository) => |
||||
_playoutRepository = playoutRepository; |
||||
public DeletePlayoutHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public async Task<Either<BaseError, Task>> Handle( |
||||
public async Task<Either<BaseError, Unit>> Handle( |
||||
DeletePlayout request, |
||||
CancellationToken cancellationToken) => |
||||
(await PlayoutMustExist(request)) |
||||
.Map(DoDeletion) |
||||
.ToEither<Task>(); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
|
||||
private Task DoDeletion(int playoutId) => _playoutRepository.Delete(playoutId); |
||||
Option<Playout> maybePlayout = await dbContext.Playouts |
||||
.OrderBy(p => p.Id) |
||||
.FirstOrDefaultAsync(p => p.Id == request.PlayoutId, cancellationToken); |
||||
|
||||
private async Task<Validation<BaseError, int>> PlayoutMustExist( |
||||
DeletePlayout deletePlayout) => |
||||
(await _playoutRepository.Get(deletePlayout.PlayoutId)) |
||||
.ToValidation<BaseError>($"Playout {deletePlayout.PlayoutId} does not exist.") |
||||
.Map(c => c.Id); |
||||
foreach (Playout playout in maybePlayout) |
||||
{ |
||||
dbContext.Playouts.Remove(playout); |
||||
await dbContext.SaveChangesAsync(cancellationToken); |
||||
} |
||||
|
||||
return maybePlayout |
||||
.Map(_ => Unit.Default) |
||||
.ToEither(BaseError.New($"Playout {request.PlayoutId} does not exist.")); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,13 +0,0 @@
@@ -1,13 +0,0 @@
|
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Domain; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Commands |
||||
{ |
||||
public record UpdatePlayout( |
||||
int PlayoutId, |
||||
int ChannelId, |
||||
int ProgramScheduleId, |
||||
ProgramSchedulePlayoutType ProgramSchedulePlayoutType) : IRequest<Either<BaseError, PlayoutViewModel>>; |
||||
} |
||||
@ -1,75 +0,0 @@
@@ -1,75 +0,0 @@
|
||||
using System.Threading; |
||||
using System.Threading.Channels; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static LanguageExt.Prelude; |
||||
using static ErsatzTV.Application.Playouts.Mapper; |
||||
using Channel = ErsatzTV.Core.Domain.Channel; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Commands |
||||
{ |
||||
public class UpdatePlayoutHandler : IRequestHandler<UpdatePlayout, Either<BaseError, PlayoutViewModel>> |
||||
{ |
||||
private readonly ChannelWriter<IBackgroundServiceRequest> _channel; |
||||
private readonly IChannelRepository _channelRepository; |
||||
private readonly IPlayoutRepository _playoutRepository; |
||||
private readonly IProgramScheduleRepository _programScheduleRepository; |
||||
|
||||
public UpdatePlayoutHandler( |
||||
IPlayoutRepository playoutRepository, |
||||
IChannelRepository channelRepository, |
||||
IProgramScheduleRepository programScheduleRepository, |
||||
ChannelWriter<IBackgroundServiceRequest> channel) |
||||
{ |
||||
_playoutRepository = playoutRepository; |
||||
_channelRepository = channelRepository; |
||||
_programScheduleRepository = programScheduleRepository; |
||||
_channel = channel; |
||||
} |
||||
|
||||
public Task<Either<BaseError, PlayoutViewModel>> Handle( |
||||
UpdatePlayout request, |
||||
CancellationToken cancellationToken) => |
||||
Validate(request) |
||||
.MapT(c => ApplyUpdateRequest(c, request)) |
||||
.Bind(v => v.ToEitherAsync()); |
||||
|
||||
private async Task<PlayoutViewModel> ApplyUpdateRequest(Playout p, UpdatePlayout update) |
||||
{ |
||||
p.ChannelId = update.ChannelId; |
||||
p.ProgramScheduleId = update.ProgramScheduleId; |
||||
p.ProgramSchedulePlayoutType = update.ProgramSchedulePlayoutType; |
||||
await _playoutRepository.Update(p); |
||||
await _channel.WriteAsync(new BuildPlayout(p.Id)); |
||||
return ProjectToViewModel(p); |
||||
} |
||||
|
||||
private async Task<Validation<BaseError, Playout>> Validate(UpdatePlayout request) => |
||||
(await PlayoutMustExist(request), await ChannelMustExist(request), await ProgramScheduleMustExist(request), |
||||
ValidatePlayoutType(request)) |
||||
.Apply( |
||||
(playoutToUpdate, _, _, _) => playoutToUpdate); |
||||
|
||||
private async Task<Validation<BaseError, Playout>> PlayoutMustExist(UpdatePlayout updatePlayout) => |
||||
(await _playoutRepository.Get(updatePlayout.PlayoutId)) |
||||
.ToValidation<BaseError>("Playout does not exist."); |
||||
|
||||
private async Task<Validation<BaseError, Channel>> ChannelMustExist(UpdatePlayout createPlayout) => |
||||
(await _channelRepository.Get(createPlayout.ChannelId)) |
||||
.ToValidation<BaseError>("Channel does not exist."); |
||||
|
||||
private async Task<Validation<BaseError, ProgramSchedule>> |
||||
ProgramScheduleMustExist(UpdatePlayout createPlayout) => |
||||
(await _programScheduleRepository.Get(createPlayout.ProgramScheduleId)) |
||||
.ToValidation<BaseError>("ProgramSchedule does not exist."); |
||||
|
||||
private Validation<BaseError, ProgramSchedulePlayoutType> ValidatePlayoutType(UpdatePlayout createPlayout) => |
||||
Optional(createPlayout.ProgramSchedulePlayoutType) |
||||
.Filter(playoutType => playoutType != ProgramSchedulePlayoutType.None) |
||||
.ToValidation<BaseError>("[ProgramSchedulePlayoutType] must not be None"); |
||||
} |
||||
} |
||||
@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
|
||||
namespace ErsatzTV.Application.Playouts |
||||
{ |
||||
public record PlayoutNameViewModel( |
||||
int PlayoutId, |
||||
string ChannelName, |
||||
string ChannelNumber, |
||||
string ScheduleName); |
||||
} |
||||
@ -1,24 +1,28 @@
@@ -1,24 +1,28 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.Playouts.Mapper; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Queries |
||||
{ |
||||
public class GetAllPlayoutsHandler : IRequestHandler<GetAllPlayouts, List<PlayoutViewModel>> |
||||
public class GetAllPlayoutsHandler : IRequestHandler<GetAllPlayouts, List<PlayoutNameViewModel>> |
||||
{ |
||||
private readonly IPlayoutRepository _playoutRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public GetAllPlayoutsHandler(IPlayoutRepository playoutRepository) => |
||||
_playoutRepository = playoutRepository; |
||||
public GetAllPlayoutsHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public Task<List<PlayoutViewModel>> Handle( |
||||
public async Task<List<PlayoutNameViewModel>> Handle( |
||||
GetAllPlayouts request, |
||||
CancellationToken cancellationToken) => |
||||
_playoutRepository.GetAll().Map(list => list.Map(ProjectToViewModel).ToList()); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
return await dbContext.Playouts |
||||
.Filter(p => p.Channel != null && p.ProgramSchedule != null) |
||||
.Map(p => new PlayoutNameViewModel(p.Id, p.Channel.Name, p.Channel.Number, p.ProgramSchedule.Name)) |
||||
.ToListAsync(cancellationToken); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Queries |
||||
{ |
||||
public record GetPlayoutById(int Id) : IRequest<Option<PlayoutViewModel>>; |
||||
} |
||||
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.Playouts.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.Playouts.Queries |
||||
{ |
||||
public class |
||||
GetPlayoutByIdHandler : IRequestHandler<GetPlayoutById, Option<PlayoutViewModel>> |
||||
{ |
||||
private readonly IPlayoutRepository _playoutRepository; |
||||
|
||||
public GetPlayoutByIdHandler(IPlayoutRepository playoutRepository) => |
||||
_playoutRepository = playoutRepository; |
||||
|
||||
public Task<Option<PlayoutViewModel>> Handle( |
||||
GetPlayoutById request, |
||||
CancellationToken cancellationToken) => |
||||
_playoutRepository.Get(request.Id) |
||||
.MapT(ProjectToViewModel); |
||||
} |
||||
} |
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Commands |
||||
{ |
||||
public record CreateProgramScheduleResult(int ProgramScheduleId) : EntityIdResult(ProgramScheduleId); |
||||
} |
||||
@ -1,9 +1,8 @@
@@ -1,9 +1,8 @@
|
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Commands |
||||
{ |
||||
public record DeleteProgramSchedule(int ProgramScheduleId) : IRequest<Either<BaseError, Task>>; |
||||
public record DeleteProgramSchedule(int ProgramScheduleId) : IRequest<Either<BaseError, LanguageExt.Unit>>; |
||||
} |
||||
|
||||
@ -1,32 +1,43 @@
@@ -1,32 +1,43 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Unit = LanguageExt.Unit; |
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Commands |
||||
{ |
||||
public class DeleteProgramScheduleHandler : IRequestHandler<DeleteProgramSchedule, Either<BaseError, Task>> |
||||
public class DeleteProgramScheduleHandler : IRequestHandler<DeleteProgramSchedule, Either<BaseError, Unit>> |
||||
{ |
||||
private readonly IProgramScheduleRepository _programScheduleRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public DeleteProgramScheduleHandler(IProgramScheduleRepository programScheduleRepository) => |
||||
_programScheduleRepository = programScheduleRepository; |
||||
public DeleteProgramScheduleHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public async Task<Either<BaseError, Task>> Handle( |
||||
public async Task<Either<BaseError, Unit>> Handle( |
||||
DeleteProgramSchedule request, |
||||
CancellationToken cancellationToken) => |
||||
(await ProgramScheduleMustExist(request)) |
||||
.Map(DoDeletion) |
||||
.ToEither<Task>(); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
Validation<BaseError, ProgramSchedule> validation = await ProgramScheduleMustExist(dbContext, request); |
||||
return await validation.Apply(ps => DoDeletion(dbContext, ps)); |
||||
} |
||||
|
||||
private Task DoDeletion(int programScheduleId) => _programScheduleRepository.Delete(programScheduleId); |
||||
private static Task<Unit> DoDeletion(TvContext dbContext, ProgramSchedule programSchedule) |
||||
{ |
||||
dbContext.ProgramSchedules.Remove(programSchedule); |
||||
return dbContext.SaveChangesAsync().ToUnit(); |
||||
} |
||||
|
||||
private async Task<Validation<BaseError, int>> ProgramScheduleMustExist( |
||||
DeleteProgramSchedule deleteProgramSchedule) => |
||||
(await _programScheduleRepository.Get(deleteProgramSchedule.ProgramScheduleId)) |
||||
.ToValidation<BaseError>($"ProgramSchedule {deleteProgramSchedule.ProgramScheduleId} does not exist.") |
||||
.Map(c => c.Id); |
||||
private Task<Validation<BaseError, ProgramSchedule>> ProgramScheduleMustExist( |
||||
TvContext dbContext, |
||||
DeleteProgramSchedule request) => |
||||
dbContext.ProgramSchedules |
||||
.SelectOneAsync(ps => ps.Id, ps => ps.Id == request.ProgramScheduleId) |
||||
.Map(o => o.ToValidation<BaseError>($"ProgramSchedule {request.ProgramScheduleId} does not exist.")); |
||||
} |
||||
} |
||||
|
||||
@ -1,79 +1,94 @@
@@ -1,79 +1,94 @@
|
||||
using System.Threading; |
||||
using System.Collections.Generic; |
||||
using System.Threading; |
||||
using System.Threading.Channels; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Application.Playouts.Commands; |
||||
using ErsatzTV.Core; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.ProgramSchedules.Mapper; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Commands |
||||
{ |
||||
public class |
||||
UpdateProgramScheduleHandler : IRequestHandler<UpdateProgramSchedule, |
||||
Either<BaseError, ProgramScheduleViewModel>> |
||||
public class UpdateProgramScheduleHandler : |
||||
IRequestHandler<UpdateProgramSchedule, Either<BaseError, UpdateProgramScheduleResult>> |
||||
{ |
||||
private readonly ChannelWriter<IBackgroundServiceRequest> _channel; |
||||
private readonly IProgramScheduleRepository _programScheduleRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public UpdateProgramScheduleHandler( |
||||
IProgramScheduleRepository programScheduleRepository, |
||||
IDbContextFactory<TvContext> dbContextFactory, |
||||
ChannelWriter<IBackgroundServiceRequest> channel) |
||||
{ |
||||
_programScheduleRepository = programScheduleRepository; |
||||
_dbContextFactory = dbContextFactory; |
||||
_channel = channel; |
||||
} |
||||
|
||||
public Task<Either<BaseError, ProgramScheduleViewModel>> Handle( |
||||
public async Task<Either<BaseError, UpdateProgramScheduleResult>> Handle( |
||||
UpdateProgramSchedule request, |
||||
CancellationToken cancellationToken) => |
||||
Validate(request) |
||||
.MapT(c => ApplyUpdateRequest(c, request)) |
||||
.Bind(v => v.ToEitherAsync()); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
|
||||
Validation<BaseError, ProgramSchedule> validation = await Validate(dbContext, request); |
||||
return await validation.Apply(ps => ApplyUpdateRequest(dbContext, ps, request)); |
||||
} |
||||
|
||||
private async Task<ProgramScheduleViewModel> ApplyUpdateRequest( |
||||
private async Task<UpdateProgramScheduleResult> ApplyUpdateRequest( |
||||
TvContext dbContext, |
||||
ProgramSchedule programSchedule, |
||||
UpdateProgramSchedule update) |
||||
UpdateProgramSchedule request) |
||||
{ |
||||
// we need to rebuild playouts if the playback order or keep multi-episodes has been modified
|
||||
bool needToRebuildPlayout = |
||||
programSchedule.MediaCollectionPlaybackOrder != update.MediaCollectionPlaybackOrder || |
||||
programSchedule.KeepMultiPartEpisodesTogether != update.KeepMultiPartEpisodesTogether || |
||||
programSchedule.TreatCollectionsAsShows != update.TreatCollectionsAsShows; |
||||
programSchedule.MediaCollectionPlaybackOrder != request.MediaCollectionPlaybackOrder || |
||||
programSchedule.KeepMultiPartEpisodesTogether != request.KeepMultiPartEpisodesTogether || |
||||
programSchedule.TreatCollectionsAsShows != request.TreatCollectionsAsShows; |
||||
|
||||
programSchedule.Name = update.Name; |
||||
programSchedule.MediaCollectionPlaybackOrder = update.MediaCollectionPlaybackOrder; |
||||
programSchedule.Name = request.Name; |
||||
programSchedule.MediaCollectionPlaybackOrder = request.MediaCollectionPlaybackOrder; |
||||
programSchedule.KeepMultiPartEpisodesTogether = |
||||
update.MediaCollectionPlaybackOrder == PlaybackOrder.Shuffle && |
||||
update.KeepMultiPartEpisodesTogether; |
||||
request.MediaCollectionPlaybackOrder == PlaybackOrder.Shuffle && |
||||
request.KeepMultiPartEpisodesTogether; |
||||
programSchedule.TreatCollectionsAsShows = programSchedule.KeepMultiPartEpisodesTogether && |
||||
update.TreatCollectionsAsShows; |
||||
await _programScheduleRepository.Update(programSchedule); |
||||
request.TreatCollectionsAsShows; |
||||
|
||||
await dbContext.SaveChangesAsync(); |
||||
|
||||
if (needToRebuildPlayout) |
||||
{ |
||||
foreach (Playout playout in programSchedule.Playouts) |
||||
List<int> playoutIds = await dbContext.Playouts |
||||
.Filter(p => p.ProgramScheduleId == programSchedule.Id) |
||||
.Map(p => p.Id) |
||||
.ToListAsync(); |
||||
|
||||
foreach (int playoutId in playoutIds) |
||||
{ |
||||
await _channel.WriteAsync(new BuildPlayout(playout.Id, true)); |
||||
await _channel.WriteAsync(new BuildPlayout(playoutId, true)); |
||||
} |
||||
} |
||||
|
||||
return ProjectToViewModel(programSchedule); |
||||
return new UpdateProgramScheduleResult(programSchedule.Id); |
||||
} |
||||
|
||||
private async Task<Validation<BaseError, ProgramSchedule>> Validate(UpdateProgramSchedule request) => |
||||
(await ProgramScheduleMustExist(request), ValidateName(request)) |
||||
.Apply((programScheduleToUpdate, _) => programScheduleToUpdate); |
||||
private static async Task<Validation<BaseError, ProgramSchedule>> Validate( |
||||
TvContext dbContext, |
||||
UpdateProgramSchedule request) => |
||||
(await ProgramScheduleMustExist(dbContext, request), ValidateName(request)) |
||||
.Apply((programSchedule, _) => programSchedule); |
||||
|
||||
private async Task<Validation<BaseError, ProgramSchedule>> ProgramScheduleMustExist( |
||||
UpdateProgramSchedule updateProgramSchedule) => |
||||
(await _programScheduleRepository.GetWithPlayouts(updateProgramSchedule.ProgramScheduleId)) |
||||
.ToValidation<BaseError>("ProgramSchedule does not exist."); |
||||
private static Task<Validation<BaseError, ProgramSchedule>> ProgramScheduleMustExist( |
||||
TvContext dbContext, |
||||
UpdateProgramSchedule request) => |
||||
dbContext.ProgramSchedules |
||||
.SelectOneAsync(ps => ps.Id, ps => ps.Id == request.ProgramScheduleId) |
||||
.Map(o => o.ToValidation<BaseError>("ProgramSchedule does not exist")); |
||||
|
||||
private Validation<BaseError, string> ValidateName(UpdateProgramSchedule updateProgramSchedule) => |
||||
updateProgramSchedule.NotEmpty(c => c.Name) |
||||
.Bind(_ => updateProgramSchedule.NotLongerThan(50)(c => c.Name)); |
||||
private static Validation<BaseError, string> ValidateName(UpdateProgramSchedule request) => |
||||
request.NotEmpty(c => c.Name) |
||||
.Bind(_ => request.NotLongerThan(50)(c => c.Name)); |
||||
} |
||||
} |
||||
|
||||
@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Commands |
||||
{ |
||||
public record UpdateProgramScheduleResult(int ProgramScheduleId) : EntityIdResult(ProgramScheduleId); |
||||
} |
||||
@ -1,23 +1,33 @@
@@ -1,23 +1,33 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.ProgramSchedules.Mapper; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Queries |
||||
{ |
||||
public class GetAllProgramSchedulesHandler : IRequestHandler<GetAllProgramSchedules, List<ProgramScheduleViewModel>> |
||||
{ |
||||
private readonly IProgramScheduleRepository _programScheduleRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public GetAllProgramSchedulesHandler(IProgramScheduleRepository programScheduleRepository) => |
||||
_programScheduleRepository = programScheduleRepository; |
||||
public GetAllProgramSchedulesHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public async Task<List<ProgramScheduleViewModel>> Handle( |
||||
GetAllProgramSchedules request, |
||||
CancellationToken cancellationToken) => |
||||
(await _programScheduleRepository.GetAll()).Map(ProjectToViewModel).ToList(); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
return await dbContext.ProgramSchedules |
||||
.Map( |
||||
ps => new ProgramScheduleViewModel( |
||||
ps.Id, |
||||
ps.Name, |
||||
ps.MediaCollectionPlaybackOrder, |
||||
ps.KeepMultiPartEpisodesTogether, |
||||
ps.TreatCollectionsAsShows)) |
||||
.ToListAsync(cancellationToken); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,24 +1,30 @@
@@ -1,24 +1,30 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using ErsatzTV.Infrastructure.Extensions; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using static ErsatzTV.Application.ProgramSchedules.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Queries |
||||
{ |
||||
public class |
||||
GetProgramScheduleByIdHandler : IRequestHandler<GetProgramScheduleById, Option<ProgramScheduleViewModel>> |
||||
public class GetProgramScheduleByIdHandler : |
||||
IRequestHandler<GetProgramScheduleById, Option<ProgramScheduleViewModel>> |
||||
{ |
||||
private readonly IProgramScheduleRepository _programScheduleRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public GetProgramScheduleByIdHandler(IProgramScheduleRepository programScheduleRepository) => |
||||
_programScheduleRepository = programScheduleRepository; |
||||
public GetProgramScheduleByIdHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public Task<Option<ProgramScheduleViewModel>> Handle( |
||||
public async Task<Option<ProgramScheduleViewModel>> Handle( |
||||
GetProgramScheduleById request, |
||||
CancellationToken cancellationToken) => |
||||
_programScheduleRepository.Get(request.Id) |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
return await dbContext.ProgramSchedules |
||||
.SelectOneAsync(ps => ps.Id, ps => ps.Id == request.Id) |
||||
.MapT(ProjectToViewModel); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,8 +1,7 @@
@@ -1,8 +1,7 @@
|
||||
using System.Collections.Generic; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Queries |
||||
{ |
||||
public record GetProgramScheduleItems(int Id) : IRequest<Option<IEnumerable<ProgramScheduleItemViewModel>>>; |
||||
public record GetProgramScheduleItems(int Id) : IRequest<List<ProgramScheduleItemViewModel>>; |
||||
} |
||||
|
||||
@ -1,25 +1,50 @@
@@ -1,25 +1,50 @@
|
||||
using System.Collections.Generic; |
||||
using System.Linq; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using ErsatzTV.Core.Domain; |
||||
using ErsatzTV.Infrastructure.Data; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using static ErsatzTV.Application.ProgramSchedules.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.ProgramSchedules.Queries |
||||
{ |
||||
public class GetProgramScheduleItemsHandler : IRequestHandler<GetProgramScheduleItems, |
||||
Option<IEnumerable<ProgramScheduleItemViewModel>>> |
||||
public class GetProgramScheduleItemsHandler : |
||||
IRequestHandler<GetProgramScheduleItems, List<ProgramScheduleItemViewModel>> |
||||
{ |
||||
private readonly IProgramScheduleRepository _programScheduleRepository; |
||||
private readonly IDbContextFactory<TvContext> _dbContextFactory; |
||||
|
||||
public GetProgramScheduleItemsHandler(IProgramScheduleRepository programScheduleRepository) => |
||||
_programScheduleRepository = programScheduleRepository; |
||||
public GetProgramScheduleItemsHandler(IDbContextFactory<TvContext> dbContextFactory) => |
||||
_dbContextFactory = dbContextFactory; |
||||
|
||||
public Task<Option<IEnumerable<ProgramScheduleItemViewModel>>> Handle( |
||||
public async Task<List<ProgramScheduleItemViewModel>> Handle( |
||||
GetProgramScheduleItems request, |
||||
CancellationToken cancellationToken) => |
||||
_programScheduleRepository.GetItems(request.Id) |
||||
.MapT(programScheduleItems => programScheduleItems.Map(ProjectToViewModel)); |
||||
CancellationToken cancellationToken) |
||||
{ |
||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext(); |
||||
return await dbContext.ProgramScheduleItems |
||||
.Filter(psi => psi.ProgramScheduleId == request.Id) |
||||
.Include(i => i.Collection) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(i => (i as Movie).MovieMetadata) |
||||
.ThenInclude(mm => mm.Artwork) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(i => (i as Season).SeasonMetadata) |
||||
.ThenInclude(sm => sm.Artwork) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(i => (i as Season).Show) |
||||
.ThenInclude(s => s.ShowMetadata) |
||||
.ThenInclude(sm => sm.Artwork) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(i => (i as Show).ShowMetadata) |
||||
.ThenInclude(sm => sm.Artwork) |
||||
.Include(i => i.MediaItem) |
||||
.ThenInclude(i => (i as Artist).ArtistMetadata) |
||||
.ThenInclude(am => am.Artwork) |
||||
.ToListAsync(cancellationToken) |
||||
.Map(programScheduleItems => programScheduleItems.Map(ProjectToViewModel).ToList()); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@ -1,7 +0,0 @@
@@ -1,7 +0,0 @@
|
||||
using LanguageExt; |
||||
using MediatR; |
||||
|
||||
namespace ErsatzTV.Application.Television.Queries |
||||
{ |
||||
public record GetTelevisionEpisodeById(int EpisodeId) : IRequest<Option<TelevisionEpisodeViewModel>>; |
||||
} |
||||
@ -1,24 +0,0 @@
@@ -1,24 +0,0 @@
|
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using ErsatzTV.Core.Interfaces.Repositories; |
||||
using LanguageExt; |
||||
using MediatR; |
||||
using static ErsatzTV.Application.Television.Mapper; |
||||
|
||||
namespace ErsatzTV.Application.Television.Queries |
||||
{ |
||||
public class |
||||
GetTelevisionEpisodeByIdHandler : IRequestHandler<GetTelevisionEpisodeById, Option<TelevisionEpisodeViewModel>> |
||||
{ |
||||
private readonly ITelevisionRepository _televisionRepository; |
||||
|
||||
public GetTelevisionEpisodeByIdHandler(ITelevisionRepository televisionRepository) => |
||||
_televisionRepository = televisionRepository; |
||||
|
||||
public Task<Option<TelevisionEpisodeViewModel>> Handle( |
||||
GetTelevisionEpisodeById request, |
||||
CancellationToken cancellationToken) => |
||||
_televisionRepository.GetEpisode(request.EpisodeId) |
||||
.MapT(ProjectToViewModel); |
||||
} |
||||
} |
||||
@ -1,10 +0,0 @@
@@ -1,10 +0,0 @@
|
||||
namespace ErsatzTV.Application.Television |
||||
{ |
||||
public record TelevisionEpisodeViewModel( |
||||
int ShowId, |
||||
int SeasonId, |
||||
int Episode, |
||||
string Title, |
||||
string Plot, |
||||
string Poster); |
||||
} |
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue