more bug reporting (#679)
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using ErsatzTV.Core;
|
using Bugsnag;
|
||||||
|
using ErsatzTV.Core;
|
||||||
using ErsatzTV.Core.Domain.Filler;
|
using ErsatzTV.Core.Domain.Filler;
|
||||||
using ErsatzTV.Infrastructure.Data;
|
using ErsatzTV.Infrastructure.Data;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@@ -7,10 +8,12 @@ namespace ErsatzTV.Application.Filler;
|
|||||||
|
|
||||||
public class CreateFillerPresetHandler : IRequestHandler<CreateFillerPreset, Either<BaseError, Unit>>
|
public class CreateFillerPresetHandler : IRequestHandler<CreateFillerPreset, Either<BaseError, Unit>>
|
||||||
{
|
{
|
||||||
|
private readonly IClient _client;
|
||||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||||
|
|
||||||
public CreateFillerPresetHandler(IDbContextFactory<TvContext> dbContextFactory)
|
public CreateFillerPresetHandler(IClient client, IDbContextFactory<TvContext> dbContextFactory)
|
||||||
{
|
{
|
||||||
|
_client = client;
|
||||||
_dbContextFactory = dbContextFactory;
|
_dbContextFactory = dbContextFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -18,7 +21,7 @@ public class CreateFillerPresetHandler : IRequestHandler<CreateFillerPreset, Eit
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext();
|
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
|
|
||||||
var fillerPreset = new FillerPreset
|
var fillerPreset = new FillerPreset
|
||||||
{
|
{
|
||||||
@@ -42,6 +45,7 @@ public class CreateFillerPresetHandler : IRequestHandler<CreateFillerPreset, Eit
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
return BaseError.New(ex.Message);
|
return BaseError.New(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using ErsatzTV.Core;
|
using Bugsnag;
|
||||||
|
using ErsatzTV.Core;
|
||||||
using ErsatzTV.Core.Domain;
|
using ErsatzTV.Core.Domain;
|
||||||
using ErsatzTV.Core.Interfaces.Scheduling;
|
using ErsatzTV.Core.Interfaces.Scheduling;
|
||||||
using ErsatzTV.Infrastructure.Data;
|
using ErsatzTV.Infrastructure.Data;
|
||||||
@@ -9,26 +10,36 @@ namespace ErsatzTV.Application.Playouts;
|
|||||||
|
|
||||||
public class BuildPlayoutHandler : MediatR.IRequestHandler<BuildPlayout, Either<BaseError, Unit>>
|
public class BuildPlayoutHandler : MediatR.IRequestHandler<BuildPlayout, Either<BaseError, Unit>>
|
||||||
{
|
{
|
||||||
|
private readonly IClient _client;
|
||||||
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
private readonly IDbContextFactory<TvContext> _dbContextFactory;
|
||||||
private readonly IPlayoutBuilder _playoutBuilder;
|
private readonly IPlayoutBuilder _playoutBuilder;
|
||||||
|
|
||||||
public BuildPlayoutHandler(IDbContextFactory<TvContext> dbContextFactory, IPlayoutBuilder playoutBuilder)
|
public BuildPlayoutHandler(IClient client, IDbContextFactory<TvContext> dbContextFactory, IPlayoutBuilder playoutBuilder)
|
||||||
{
|
{
|
||||||
|
_client = client;
|
||||||
_dbContextFactory = dbContextFactory;
|
_dbContextFactory = dbContextFactory;
|
||||||
_playoutBuilder = playoutBuilder;
|
_playoutBuilder = playoutBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Either<BaseError, Unit>> Handle(BuildPlayout request, CancellationToken cancellationToken)
|
public async Task<Either<BaseError, Unit>> Handle(BuildPlayout request, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await using TvContext dbContext = _dbContextFactory.CreateDbContext();
|
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
|
||||||
Validation<BaseError, Playout> validation = await Validate(dbContext, request);
|
Validation<BaseError, Playout> validation = await Validate(dbContext, request);
|
||||||
return await LanguageExtensions.Apply(validation, playout => ApplyUpdateRequest(dbContext, request, playout));
|
return await validation.Apply(playout => ApplyUpdateRequest(dbContext, request, playout));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Unit> ApplyUpdateRequest(TvContext dbContext, BuildPlayout request, Playout playout)
|
private async Task<Unit> ApplyUpdateRequest(TvContext dbContext, BuildPlayout request, Playout playout)
|
||||||
{
|
{
|
||||||
await _playoutBuilder.BuildPlayoutItems(playout, request.Rebuild);
|
try
|
||||||
await dbContext.SaveChangesAsync();
|
{
|
||||||
|
await _playoutBuilder.BuildPlayoutItems(playout, request.Rebuild);
|
||||||
|
await dbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
|
}
|
||||||
|
|
||||||
return Unit.Default;
|
return Unit.Default;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+129
-128
@@ -18,8 +18,7 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
|
|
||||||
namespace ErsatzTV.Application.Streaming;
|
namespace ErsatzTV.Application.Streaming;
|
||||||
|
|
||||||
public class GetPlayoutItemProcessByChannelNumberHandler :
|
public class GetPlayoutItemProcessByChannelNumberHandler : FFmpegProcessHandler<GetPlayoutItemProcessByChannelNumber>
|
||||||
FFmpegProcessHandler<GetPlayoutItemProcessByChannelNumber>
|
|
||||||
{
|
{
|
||||||
private readonly IEmbyPathReplacementService _embyPathReplacementService;
|
private readonly IEmbyPathReplacementService _embyPathReplacementService;
|
||||||
private readonly IMediaCollectionRepository _mediaCollectionRepository;
|
private readonly IMediaCollectionRepository _mediaCollectionRepository;
|
||||||
@@ -62,7 +61,7 @@ public class GetPlayoutItemProcessByChannelNumberHandler :
|
|||||||
string ffmpegPath)
|
string ffmpegPath)
|
||||||
{
|
{
|
||||||
DateTimeOffset now = request.Now;
|
DateTimeOffset now = request.Now;
|
||||||
|
|
||||||
Either<BaseError, PlayoutItemWithPath> maybePlayoutItem = await dbContext.PlayoutItems
|
Either<BaseError, PlayoutItemWithPath> maybePlayoutItem = await dbContext.PlayoutItems
|
||||||
.Include(i => i.MediaItem)
|
.Include(i => i.MediaItem)
|
||||||
.ThenInclude(mi => (mi as Episode).MediaVersions)
|
.ThenInclude(mi => (mi as Episode).MediaVersions)
|
||||||
@@ -108,144 +107,146 @@ public class GetPlayoutItemProcessByChannelNumberHandler :
|
|||||||
|
|
||||||
IFFmpegProcessService ffmpegProcessService = await _ffmpegProcessServiceFactory.GetService();
|
IFFmpegProcessService ffmpegProcessService = await _ffmpegProcessServiceFactory.GetService();
|
||||||
|
|
||||||
return await maybePlayoutItem.Match(
|
foreach (PlayoutItemWithPath playoutItemWithPath in maybePlayoutItem.RightToSeq())
|
||||||
async playoutItemWithPath =>
|
{
|
||||||
|
MediaVersion version = playoutItemWithPath.PlayoutItem.MediaItem.GetHeadVersion();
|
||||||
|
|
||||||
|
string videoPath = playoutItemWithPath.Path;
|
||||||
|
MediaVersion videoVersion = version;
|
||||||
|
|
||||||
|
string audioPath = playoutItemWithPath.Path;
|
||||||
|
MediaVersion audioVersion = version;
|
||||||
|
|
||||||
|
Option<ChannelWatermark> maybeGlobalWatermark = await dbContext.ConfigElements
|
||||||
|
.GetValue<int>(ConfigElementKey.FFmpegGlobalWatermarkId)
|
||||||
|
.BindT(
|
||||||
|
watermarkId => dbContext.ChannelWatermarks
|
||||||
|
.SelectOneAsync(w => w.Id, w => w.Id == watermarkId));
|
||||||
|
|
||||||
|
if (playoutItemWithPath.PlayoutItem.MediaItem is Song song)
|
||||||
{
|
{
|
||||||
MediaVersion version = playoutItemWithPath.PlayoutItem.MediaItem.GetHeadVersion();
|
(videoPath, videoVersion) = await _songVideoGenerator.GenerateSongVideo(
|
||||||
|
song,
|
||||||
string videoPath = playoutItemWithPath.Path;
|
|
||||||
MediaVersion videoVersion = version;
|
|
||||||
|
|
||||||
string audioPath = playoutItemWithPath.Path;
|
|
||||||
MediaVersion audioVersion = version;
|
|
||||||
|
|
||||||
Option<ChannelWatermark> maybeGlobalWatermark = await dbContext.ConfigElements
|
|
||||||
.GetValue<int>(ConfigElementKey.FFmpegGlobalWatermarkId)
|
|
||||||
.BindT(
|
|
||||||
watermarkId => dbContext.ChannelWatermarks
|
|
||||||
.SelectOneAsync(w => w.Id, w => w.Id == watermarkId));
|
|
||||||
|
|
||||||
if (playoutItemWithPath.PlayoutItem.MediaItem is Song song)
|
|
||||||
{
|
|
||||||
(videoPath, videoVersion) = await _songVideoGenerator.GenerateSongVideo(
|
|
||||||
song,
|
|
||||||
channel,
|
|
||||||
maybeGlobalWatermark,
|
|
||||||
ffmpegPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool saveReports = await dbContext.ConfigElements
|
|
||||||
.GetValue<bool>(ConfigElementKey.FFmpegSaveReports)
|
|
||||||
.Map(result => result.IfNone(false));
|
|
||||||
|
|
||||||
Process process = await ffmpegProcessService.ForPlayoutItem(
|
|
||||||
ffmpegPath,
|
|
||||||
saveReports,
|
|
||||||
channel,
|
channel,
|
||||||
videoVersion,
|
|
||||||
audioVersion,
|
|
||||||
videoPath,
|
|
||||||
audioPath,
|
|
||||||
playoutItemWithPath.PlayoutItem.StartOffset,
|
|
||||||
playoutItemWithPath.PlayoutItem.FinishOffset,
|
|
||||||
request.StartAtZero ? playoutItemWithPath.PlayoutItem.StartOffset : now,
|
|
||||||
maybeGlobalWatermark,
|
maybeGlobalWatermark,
|
||||||
channel.FFmpegProfile.VaapiDriver,
|
ffmpegPath);
|
||||||
channel.FFmpegProfile.VaapiDevice,
|
}
|
||||||
request.HlsRealtime,
|
|
||||||
playoutItemWithPath.PlayoutItem.FillerKind,
|
|
||||||
playoutItemWithPath.PlayoutItem.InPoint,
|
|
||||||
playoutItemWithPath.PlayoutItem.OutPoint,
|
|
||||||
request.PtsOffset,
|
|
||||||
request.TargetFramerate);
|
|
||||||
|
|
||||||
var result = new PlayoutItemProcessModel(process, playoutItemWithPath.PlayoutItem.FinishOffset);
|
bool saveReports = await dbContext.ConfigElements
|
||||||
|
.GetValue<bool>(ConfigElementKey.FFmpegSaveReports)
|
||||||
|
.Map(result => result.IfNone(false));
|
||||||
|
|
||||||
return Right<BaseError, PlayoutItemProcessModel>(result);
|
Process process = await ffmpegProcessService.ForPlayoutItem(
|
||||||
},
|
ffmpegPath,
|
||||||
async error =>
|
saveReports,
|
||||||
|
channel,
|
||||||
|
videoVersion,
|
||||||
|
audioVersion,
|
||||||
|
videoPath,
|
||||||
|
audioPath,
|
||||||
|
playoutItemWithPath.PlayoutItem.StartOffset,
|
||||||
|
playoutItemWithPath.PlayoutItem.FinishOffset,
|
||||||
|
request.StartAtZero ? playoutItemWithPath.PlayoutItem.StartOffset : now,
|
||||||
|
maybeGlobalWatermark,
|
||||||
|
channel.FFmpegProfile.VaapiDriver,
|
||||||
|
channel.FFmpegProfile.VaapiDevice,
|
||||||
|
request.HlsRealtime,
|
||||||
|
playoutItemWithPath.PlayoutItem.FillerKind,
|
||||||
|
playoutItemWithPath.PlayoutItem.InPoint,
|
||||||
|
playoutItemWithPath.PlayoutItem.OutPoint,
|
||||||
|
request.PtsOffset,
|
||||||
|
request.TargetFramerate);
|
||||||
|
|
||||||
|
var result = new PlayoutItemProcessModel(process, playoutItemWithPath.PlayoutItem.FinishOffset);
|
||||||
|
|
||||||
|
return Right<BaseError, PlayoutItemProcessModel>(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (BaseError error in maybePlayoutItem.LeftToSeq())
|
||||||
|
{
|
||||||
|
var offlineTranscodeMessage =
|
||||||
|
$"offline image is unavailable because transcoding is disabled in ffmpeg profile '{channel.FFmpegProfile.Name}'";
|
||||||
|
|
||||||
|
Option<TimeSpan> maybeDuration = await Optional(channel.FFmpegProfile.Transcode)
|
||||||
|
.Where(transcode => transcode)
|
||||||
|
.Match(
|
||||||
|
_ => dbContext.PlayoutItems
|
||||||
|
.Filter(pi => pi.Playout.ChannelId == channel.Id)
|
||||||
|
.Filter(pi => pi.Start > now.UtcDateTime)
|
||||||
|
.OrderBy(pi => pi.Start)
|
||||||
|
.FirstOrDefaultAsync()
|
||||||
|
.Map(Optional)
|
||||||
|
.MapT(pi => pi.StartOffset - now),
|
||||||
|
() => Option<TimeSpan>.None.AsTask());
|
||||||
|
|
||||||
|
DateTimeOffset finish = maybeDuration.Match(d => now.Add(d), () => now);
|
||||||
|
|
||||||
|
switch (error)
|
||||||
{
|
{
|
||||||
var offlineTranscodeMessage =
|
case UnableToLocatePlayoutItem:
|
||||||
$"offline image is unavailable because transcoding is disabled in ffmpeg profile '{channel.FFmpegProfile.Name}'";
|
if (channel.FFmpegProfile.Transcode)
|
||||||
|
{
|
||||||
|
Process errorProcess = await ffmpegProcessService.ForError(
|
||||||
|
ffmpegPath,
|
||||||
|
channel,
|
||||||
|
maybeDuration,
|
||||||
|
"Channel is Offline",
|
||||||
|
request.HlsRealtime,
|
||||||
|
request.PtsOffset);
|
||||||
|
|
||||||
Option<TimeSpan> maybeDuration = await Optional(channel.FFmpegProfile.Transcode)
|
return new PlayoutItemProcessModel(errorProcess, finish);
|
||||||
.Where(transcode => transcode)
|
}
|
||||||
.Match(
|
else
|
||||||
_ => dbContext.PlayoutItems
|
{
|
||||||
.Filter(pi => pi.Playout.ChannelId == channel.Id)
|
var message =
|
||||||
.Filter(pi => pi.Start > now.UtcDateTime)
|
$"Unable to locate playout item for channel {channel.Number}; {offlineTranscodeMessage}";
|
||||||
.OrderBy(pi => pi.Start)
|
|
||||||
.FirstOrDefaultAsync()
|
|
||||||
.Map(Optional)
|
|
||||||
.MapT(pi => pi.StartOffset - now),
|
|
||||||
() => Option<TimeSpan>.None.AsTask());
|
|
||||||
|
|
||||||
DateTimeOffset finish = maybeDuration.Match(d => now.Add(d), () => now);
|
return BaseError.New(message);
|
||||||
|
}
|
||||||
|
case PlayoutItemDoesNotExistOnDisk:
|
||||||
|
if (channel.FFmpegProfile.Transcode)
|
||||||
|
{
|
||||||
|
Process errorProcess = await ffmpegProcessService.ForError(
|
||||||
|
ffmpegPath,
|
||||||
|
channel,
|
||||||
|
maybeDuration,
|
||||||
|
error.Value,
|
||||||
|
request.HlsRealtime,
|
||||||
|
request.PtsOffset);
|
||||||
|
|
||||||
switch (error)
|
return new PlayoutItemProcessModel(errorProcess, finish);
|
||||||
{
|
}
|
||||||
case UnableToLocatePlayoutItem:
|
else
|
||||||
if (channel.FFmpegProfile.Transcode)
|
{
|
||||||
{
|
var message =
|
||||||
Process errorProcess = await ffmpegProcessService.ForError(
|
$"Playout item does not exist on disk for channel {channel.Number}; {offlineTranscodeMessage}";
|
||||||
ffmpegPath,
|
|
||||||
channel,
|
|
||||||
maybeDuration,
|
|
||||||
"Channel is Offline",
|
|
||||||
request.HlsRealtime,
|
|
||||||
request.PtsOffset);
|
|
||||||
|
|
||||||
return new PlayoutItemProcessModel(errorProcess, finish);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var message =
|
|
||||||
$"Unable to locate playout item for channel {channel.Number}; {offlineTranscodeMessage}";
|
|
||||||
|
|
||||||
return BaseError.New(message);
|
return BaseError.New(message);
|
||||||
}
|
}
|
||||||
case PlayoutItemDoesNotExistOnDisk:
|
default:
|
||||||
if (channel.FFmpegProfile.Transcode)
|
if (channel.FFmpegProfile.Transcode)
|
||||||
{
|
{
|
||||||
Process errorProcess = await ffmpegProcessService.ForError(
|
Process errorProcess = await ffmpegProcessService.ForError(
|
||||||
ffmpegPath,
|
ffmpegPath,
|
||||||
channel,
|
channel,
|
||||||
maybeDuration,
|
maybeDuration,
|
||||||
error.Value,
|
"Channel is Offline",
|
||||||
request.HlsRealtime,
|
request.HlsRealtime,
|
||||||
request.PtsOffset);
|
request.PtsOffset);
|
||||||
|
|
||||||
return new PlayoutItemProcessModel(errorProcess, finish);
|
return new PlayoutItemProcessModel(errorProcess, finish);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var message =
|
var message =
|
||||||
$"Playout item does not exist on disk for channel {channel.Number}; {offlineTranscodeMessage}";
|
$"Unexpected error locating playout item for channel {channel.Number}; {offlineTranscodeMessage}";
|
||||||
|
|
||||||
return BaseError.New(message);
|
return BaseError.New(message);
|
||||||
}
|
}
|
||||||
default:
|
}
|
||||||
if (channel.FFmpegProfile.Transcode)
|
}
|
||||||
{
|
|
||||||
Process errorProcess = await ffmpegProcessService.ForError(
|
|
||||||
ffmpegPath,
|
|
||||||
channel,
|
|
||||||
maybeDuration,
|
|
||||||
"Channel is Offline",
|
|
||||||
request.HlsRealtime,
|
|
||||||
request.PtsOffset);
|
|
||||||
|
|
||||||
return new PlayoutItemProcessModel(errorProcess, finish);
|
return BaseError.New($"Unexpected error locating playout item for channel {channel.Number}");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var message =
|
|
||||||
$"Unexpected error locating playout item for channel {channel.Number}; {offlineTranscodeMessage}";
|
|
||||||
|
|
||||||
return BaseError.New(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<Either<BaseError, PlayoutItemWithPath>> CheckForFallbackFiller(
|
private async Task<Either<BaseError, PlayoutItemWithPath>> CheckForFallbackFiller(
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ public class TranscodingTests
|
|||||||
|
|
||||||
var localStatisticsProvider = new LocalStatisticsProvider(
|
var localStatisticsProvider = new LocalStatisticsProvider(
|
||||||
metadataRepository.Object,
|
metadataRepository.Object,
|
||||||
new LocalFileSystem(LoggerFactory.CreateLogger<LocalFileSystem>()),
|
new LocalFileSystem(new Mock<IClient>().Object, LoggerFactory.CreateLogger<LocalFileSystem>()),
|
||||||
new Mock<IClient>().Object,
|
new Mock<IClient>().Object,
|
||||||
LoggerFactory.CreateLogger<LocalStatisticsProvider>());
|
LoggerFactory.CreateLogger<LocalStatisticsProvider>());
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using ErsatzTV.Core.Domain;
|
using Bugsnag;
|
||||||
|
using ErsatzTV.Core.Domain;
|
||||||
using ErsatzTV.Core.Interfaces.Metadata;
|
using ErsatzTV.Core.Interfaces.Metadata;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
@@ -6,10 +7,12 @@ namespace ErsatzTV.Core.Metadata;
|
|||||||
|
|
||||||
public class LocalFileSystem : ILocalFileSystem
|
public class LocalFileSystem : ILocalFileSystem
|
||||||
{
|
{
|
||||||
|
private readonly IClient _client;
|
||||||
private readonly ILogger<LocalFileSystem> _logger;
|
private readonly ILogger<LocalFileSystem> _logger;
|
||||||
|
|
||||||
public LocalFileSystem(ILogger<LocalFileSystem> logger)
|
public LocalFileSystem(IClient client, ILogger<LocalFileSystem> logger)
|
||||||
{
|
{
|
||||||
|
_client = client;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,9 +47,10 @@ public class LocalFileSystem : ILocalFileSystem
|
|||||||
{
|
{
|
||||||
return Directory.EnumerateDirectories(folder);
|
return Directory.EnumerateDirectories(folder);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
|
_client.Notify(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,9 +65,10 @@ public class LocalFileSystem : ILocalFileSystem
|
|||||||
{
|
{
|
||||||
return Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly);
|
return Directory.EnumerateFiles(folder, "*", SearchOption.TopDirectoryOnly);
|
||||||
}
|
}
|
||||||
catch
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// do nothing
|
// do nothing
|
||||||
|
_client.Notify(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,6 +97,7 @@ public class LocalFileSystem : ILocalFileSystem
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
return BaseError.New(ex.ToString());
|
return BaseError.New(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
|
|||||||
private readonly ILocalMetadataProvider _localMetadataProvider;
|
private readonly ILocalMetadataProvider _localMetadataProvider;
|
||||||
private readonly ILogger<TelevisionFolderScanner> _logger;
|
private readonly ILogger<TelevisionFolderScanner> _logger;
|
||||||
private readonly IMediator _mediator;
|
private readonly IMediator _mediator;
|
||||||
|
private readonly IClient _client;
|
||||||
private readonly IMetadataRepository _metadataRepository;
|
private readonly IMetadataRepository _metadataRepository;
|
||||||
private readonly ISearchIndex _searchIndex;
|
private readonly ISearchIndex _searchIndex;
|
||||||
private readonly ISearchRepository _searchRepository;
|
private readonly ISearchRepository _searchRepository;
|
||||||
@@ -57,6 +58,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
|
|||||||
_searchRepository = searchRepository;
|
_searchRepository = searchRepository;
|
||||||
_libraryRepository = libraryRepository;
|
_libraryRepository = libraryRepository;
|
||||||
_mediator = mediator;
|
_mediator = mediator;
|
||||||
|
_client = client;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,6 +289,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
return BaseError.New(ex.ToString());
|
return BaseError.New(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,6 +351,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
return BaseError.New(ex.ToString());
|
return BaseError.New(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,6 +375,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
return BaseError.New(ex.ToString());
|
return BaseError.New(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -390,6 +395,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
return BaseError.New(ex.ToString());
|
return BaseError.New(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -411,6 +417,7 @@ public class TelevisionFolderScanner : LocalFolderScanner, ITelevisionFolderScan
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
_client.Notify(ex);
|
||||||
return BaseError.New(ex.ToString());
|
return BaseError.New(ex.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user