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.
96 lines
4.5 KiB
96 lines
4.5 KiB
using System.IO; |
|
using System.Threading; |
|
using System.Threading.Tasks; |
|
using ErsatzTV.Core; |
|
using ErsatzTV.Core.Domain; |
|
using ErsatzTV.Core.Interfaces.Metadata; |
|
using ErsatzTV.Core.Interfaces.Repositories; |
|
using LanguageExt; |
|
using MediatR; |
|
using static LanguageExt.Prelude; |
|
using static ErsatzTV.Application.MediaItems.Mapper; |
|
|
|
namespace ErsatzTV.Application.MediaItems.Commands |
|
{ |
|
public class CreateMediaItemHandler : IRequestHandler<CreateMediaItem, Either<BaseError, MediaItemViewModel>> |
|
{ |
|
private readonly IConfigElementRepository _configElementRepository; |
|
private readonly ILocalMetadataProvider _localMetadataProvider; |
|
private readonly ILocalStatisticsProvider _localStatisticsProvider; |
|
private readonly IMediaItemRepository _mediaItemRepository; |
|
private readonly IMediaSourceRepository _mediaSourceRepository; |
|
private readonly ISmartCollectionBuilder _smartCollectionBuilder; |
|
|
|
public CreateMediaItemHandler( |
|
IMediaItemRepository mediaItemRepository, |
|
IMediaSourceRepository mediaSourceRepository, |
|
IConfigElementRepository configElementRepository, |
|
ISmartCollectionBuilder smartCollectionBuilder, |
|
ILocalMetadataProvider localMetadataProvider, |
|
ILocalStatisticsProvider localStatisticsProvider) |
|
{ |
|
_mediaItemRepository = mediaItemRepository; |
|
_mediaSourceRepository = mediaSourceRepository; |
|
_configElementRepository = configElementRepository; |
|
_smartCollectionBuilder = smartCollectionBuilder; |
|
_localMetadataProvider = localMetadataProvider; |
|
_localStatisticsProvider = localStatisticsProvider; |
|
} |
|
|
|
public Task<Either<BaseError, MediaItemViewModel>> Handle( |
|
CreateMediaItem request, |
|
CancellationToken cancellationToken) => |
|
Validate(request) |
|
.MapT(PersistMediaItem) |
|
.Bind(v => v.ToEitherAsync()); |
|
|
|
private async Task<MediaItemViewModel> PersistMediaItem(RequestParameters parameters) |
|
{ |
|
await _mediaItemRepository.Add(parameters.MediaItem); |
|
|
|
await _localStatisticsProvider.RefreshStatistics(parameters.FFprobePath, parameters.MediaItem); |
|
await _localMetadataProvider.RefreshMetadata(parameters.MediaItem); |
|
await _smartCollectionBuilder.RefreshSmartCollections(parameters.MediaItem); |
|
|
|
return ProjectToViewModel(parameters.MediaItem); |
|
} |
|
|
|
private async Task<Validation<BaseError, RequestParameters>> Validate(CreateMediaItem request) => |
|
(await ValidateMediaSource(request), PathMustExist(request), await ValidateFFprobePath()) |
|
.Apply( |
|
(mediaSourceId, path, ffprobePath) => new RequestParameters( |
|
ffprobePath, |
|
new MediaItem |
|
{ |
|
MediaSourceId = mediaSourceId, |
|
Path = path |
|
})); |
|
|
|
private async Task<Validation<BaseError, int>> ValidateMediaSource(CreateMediaItem createMediaItem) => |
|
(await MediaSourceMustExist(createMediaItem)).Bind(MediaSourceMustBeLocal); |
|
|
|
private async Task<Validation<BaseError, MediaSource>> MediaSourceMustExist(CreateMediaItem createMediaItem) => |
|
(await _mediaSourceRepository.Get(createMediaItem.MediaSourceId)) |
|
.ToValidation<BaseError>($"[MediaSource] {createMediaItem.MediaSourceId} does not exist."); |
|
|
|
private Validation<BaseError, int> MediaSourceMustBeLocal(MediaSource mediaSource) => |
|
Some(mediaSource) |
|
.Filter(ms => ms is LocalMediaSource) |
|
.ToValidation<BaseError>($"[MediaSource] {mediaSource.Id} must be a local media source") |
|
.Map(ms => ms.Id); |
|
|
|
private Validation<BaseError, string> PathMustExist(CreateMediaItem createMediaItem) => |
|
Some(createMediaItem.Path) |
|
.Filter(File.Exists) |
|
.ToValidation<BaseError>("[Path] does not exist on the file system"); |
|
|
|
private Task<Validation<BaseError, string>> ValidateFFprobePath() => |
|
_configElementRepository.GetValue<string>(ConfigElementKey.FFprobePath) |
|
.FilterT(File.Exists) |
|
.Map( |
|
ffprobePath => |
|
ffprobePath.ToValidation<BaseError>("FFprobe path does not exist on the file system")); |
|
|
|
private record RequestParameters(string FFprobePath, MediaItem MediaItem); |
|
} |
|
}
|
|
|