Browse Source

adjust block unique constraint (#1634)

* upgrade dependencies

* allow blocks with same name in different groups

* code cleanup
pull/1636/head
Jason Dove 1 year ago committed by GitHub
parent
commit
087901d177
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 2
      .config/dotnet-tools.json
  2. 3
      ErsatzTV.Application/Channels/Commands/CreateChannel.cs
  3. 2
      ErsatzTV.Application/Channels/Commands/DeleteChannelHandler.cs
  4. 112
      ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs
  5. 10
      ErsatzTV.Application/Channels/Commands/RefreshChannelListHandler.cs
  6. 3
      ErsatzTV.Application/Channels/Commands/UpdateChannel.cs
  7. 4
      ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs
  8. 4
      ErsatzTV.Application/Channels/Queries/GetChannelGuide.cs
  9. 18
      ErsatzTV.Application/Configuration/Commands/UpdateGeneralSettingsHandler.cs
  10. 2
      ErsatzTV.Application/Configuration/Commands/UpdateXmltvSettingsHandler.cs
  11. 6
      ErsatzTV.Application/Configuration/Queries/GetGeneralSettingsHandler.cs
  12. 3
      ErsatzTV.Application/Emby/Commands/UpdateEmbyLibraryPreferences.cs
  13. 2
      ErsatzTV.Application/Emby/Commands/UpdateEmbyLibraryPreferencesHandler.cs
  14. 10
      ErsatzTV.Application/Emby/EmbyLibraryViewModel.cs
  15. 3
      ErsatzTV.Application/Emby/Queries/GetEmbyPathReplacementsBySourceId.cs
  16. 4
      ErsatzTV.Application/ErsatzTV.Application.csproj
  17. 3
      ErsatzTV.Application/FFmpegProfiles/Commands/CopyFFmpegProfile.cs
  18. 4
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfileHandler.cs
  19. 4
      ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs
  20. 2
      ErsatzTV.Application/FFmpegProfiles/Queries/GetFFmpegProfileByIdForApiHandler.cs
  21. 2
      ErsatzTV.Application/FFmpegProfiles/Queries/GetSupportedHardwareAccelerationKindsHandler.cs
  22. 12
      ErsatzTV.Application/Images/Commands/UpdateImageFolderDurationHandler.cs
  23. 5
      ErsatzTV.Application/Images/Queries/GetCachedImagePath.cs
  24. 2
      ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinAdminUserIdHandler.cs
  25. 4
      ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryById.cs
  26. 4
      ErsatzTV.Application/Jellyfin/Commands/UpdateJellyfinLibraryPreferences.cs
  27. 2
      ErsatzTV.Application/Jellyfin/Commands/UpdateJellyfinLibraryPreferencesHandler.cs
  28. 10
      ErsatzTV.Application/Jellyfin/JellyfinLibraryViewModel.cs
  29. 2
      ErsatzTV.Application/Jellyfin/Queries/GetAllJellyfinMediaSourcesHandler.cs
  30. 2
      ErsatzTV.Application/Jellyfin/Queries/GetJellyfinLibrariesBySourceIdHandler.cs
  31. 3
      ErsatzTV.Application/Jellyfin/Queries/GetJellyfinMediaSourceById.cs
  32. 2
      ErsatzTV.Application/Jellyfin/Queries/GetJellyfinMediaSourceByIdHandler.cs
  33. 4
      ErsatzTV.Application/Jellyfin/Queries/GetJellyfinPathReplacementsBySourceId.cs
  34. 11
      ErsatzTV.Application/Libraries/Commands/CallLibraryScannerHandler.cs
  35. 2
      ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryHandler.cs
  36. 4
      ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryPath.cs
  37. 2
      ErsatzTV.Application/Libraries/Commands/DeleteLocalLibraryHandler.cs
  38. 2
      ErsatzTV.Application/Libraries/Commands/MoveLocalLibraryPathHandler.cs
  39. 2
      ErsatzTV.Application/Libraries/Commands/UpdateLocalLibraryHandler.cs
  40. 10
      ErsatzTV.Application/Libraries/PlexLibraryViewModel.cs
  41. 3
      ErsatzTV.Application/MediaCards/ArtistCardViewModel.cs
  42. 3
      ErsatzTV.Application/MediaCards/ImageCardViewModel.cs
  43. 3
      ErsatzTV.Application/MediaCards/MovieCardViewModel.cs
  44. 3
      ErsatzTV.Application/MediaCards/MusicVideoCardViewModel.cs
  45. 3
      ErsatzTV.Application/MediaCards/OtherVideoCardViewModel.cs
  46. 3
      ErsatzTV.Application/MediaCards/Queries/GetMusicVideoCards.cs
  47. 4
      ErsatzTV.Application/MediaCards/Queries/GetTelevisionEpisodeCards.cs
  48. 4
      ErsatzTV.Application/MediaCards/Queries/GetTelevisionSeasonCards.cs
  49. 2
      ErsatzTV.Application/MediaCards/Queries/GetTelevisionSeasonCardsHandler.cs
  50. 3
      ErsatzTV.Application/MediaCards/SongCardViewModel.cs
  51. 3
      ErsatzTV.Application/MediaCards/TelevisionEpisodeCardViewModel.cs
  52. 3
      ErsatzTV.Application/MediaCards/TelevisionSeasonCardViewModel.cs
  53. 3
      ErsatzTV.Application/MediaCards/TelevisionShowCardViewModel.cs
  54. 3
      ErsatzTV.Application/MediaCollections/Commands/AddArtistToCollection.cs
  55. 2
      ErsatzTV.Application/MediaCollections/Commands/AddArtistToCollectionHandler.cs
  56. 4
      ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToCollectionHandler.cs
  57. 3
      ErsatzTV.Application/MediaCollections/Commands/AddItemsToCollection.cs
  58. 2
      ErsatzTV.Application/MediaCollections/Commands/AddMovieToCollectionHandler.cs
  59. 3
      ErsatzTV.Application/MediaCollections/Commands/AddMusicVideoToCollection.cs
  60. 4
      ErsatzTV.Application/MediaCollections/Commands/AddMusicVideoToCollectionHandler.cs
  61. 3
      ErsatzTV.Application/MediaCollections/Commands/AddOtherVideoToCollection.cs
  62. 4
      ErsatzTV.Application/MediaCollections/Commands/AddOtherVideoToCollectionHandler.cs
  63. 2
      ErsatzTV.Application/MediaCollections/Commands/AddSeasonToCollectionHandler.cs
  64. 2
      ErsatzTV.Application/MediaCollections/Commands/AddShowToCollectionHandler.cs
  65. 3
      ErsatzTV.Application/MediaCollections/Commands/AddSongToCollection.cs
  66. 2
      ErsatzTV.Application/MediaCollections/Commands/AddSongToCollectionHandler.cs
  67. 4
      ErsatzTV.Application/MediaCollections/Commands/CreateMultiCollection.cs
  68. 3
      ErsatzTV.Application/MediaCollections/Commands/CreateSmartCollection.cs
  69. 2
      ErsatzTV.Application/MediaCollections/Commands/DeleteTraktListHandler.cs
  70. 2
      ErsatzTV.Application/MediaCollections/Commands/RemoveItemsFromCollectionHandler.cs
  71. 3
      ErsatzTV.Application/MediaCollections/Commands/UpdateCollection.cs
  72. 3
      ErsatzTV.Application/MediaCollections/Commands/UpdateCollectionCustomOrder.cs
  73. 2
      ErsatzTV.Application/MediaCollections/Commands/UpdateCollectionCustomOrderHandler.cs
  74. 4
      ErsatzTV.Application/MediaCollections/Commands/UpdateCollectionHandler.cs
  75. 3
      ErsatzTV.Application/MediaCollections/Commands/UpdateMultiCollection.cs
  76. 6
      ErsatzTV.Application/MediaCollections/Commands/UpdateMultiCollectionHandler.cs
  77. 2
      ErsatzTV.Application/MediaCollections/Commands/UpdateSmartCollectionHandler.cs
  78. 7
      ErsatzTV.Application/Playouts/Commands/BuildPlayoutHandler.cs
  79. 4
      ErsatzTV.Application/Playouts/Commands/CreateExternalJsonPlayoutHandler.cs
  80. 4
      ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs
  81. 4
      ErsatzTV.Application/Playouts/Commands/ReplacePlayoutAlternateScheduleItems.cs
  82. 8
      ErsatzTV.Application/Playouts/Commands/UpdateExternalJsonPlayoutHandler.cs
  83. 4
      ErsatzTV.Application/Playouts/Commands/UpdatePlayout.cs
  84. 4
      ErsatzTV.Application/Playouts/Queries/GetFuturePlayoutItemsById.cs
  85. 3
      ErsatzTV.Application/Plex/Commands/UpdatePlexLibraryPreferences.cs
  86. 2
      ErsatzTV.Application/Plex/Commands/UpdatePlexLibraryPreferencesHandler.cs
  87. 3
      ErsatzTV.Application/Plex/Commands/UpdatePlexPathReplacements.cs
  88. 4
      ErsatzTV.Application/Plex/Queries/GetPlexConnectionParameters.cs
  89. 3
      ErsatzTV.Application/Plex/Queries/GetPlexPathReplacementsBySourceId.cs
  90. 2
      ErsatzTV.Application/ProgramSchedules/Commands/AddProgramScheduleItemHandler.cs
  91. 4
      ErsatzTV.Application/ProgramSchedules/Commands/CopyProgramSchedule.cs
  92. 5
      ErsatzTV.Application/ProgramSchedules/Commands/ReplaceProgramScheduleItems.cs
  93. 3
      ErsatzTV.Application/ProgramSchedules/Commands/UpdateProgramSchedule.cs
  94. 2
      ErsatzTV.Application/ProgramSchedules/Commands/UpdateProgramScheduleHandler.cs
  95. 8
      ErsatzTV.Application/Scheduling/Commands/CreateBlockGroupHandler.cs
  96. 39
      ErsatzTV.Application/Scheduling/Commands/CreateBlockHandler.cs
  97. 2
      ErsatzTV.Application/Scheduling/Commands/EraseBlockPlayoutItemsHandler.cs
  98. 6
      ErsatzTV.Application/Scheduling/Commands/ReplaceBlockItemsHandler.cs
  99. 4
      ErsatzTV.Application/Scheduling/Commands/ReplacePlayoutTemplateItemsHandler.cs
  100. 3
      ErsatzTV.Application/Scheduling/Queries/GetTemplateItemsHandler.cs
  101. Some files were not shown because too many files have changed in this diff Show More

2
.config/dotnet-tools.json

@ -3,7 +3,7 @@ @@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"jetbrains.resharper.globaltools": {
"version": "2023.2.0",
"version": "2023.3.3",
"commands": [
"jb"
]

3
ErsatzTV.Application/Channels/Commands/CreateChannel.cs

@ -3,8 +3,7 @@ using ErsatzTV.Core.Domain; @@ -3,8 +3,7 @@ using ErsatzTV.Core.Domain;
namespace ErsatzTV.Application.Channels;
public record CreateChannel
(
public record CreateChannel(
string Name,
string Number,
string Group,

2
ErsatzTV.Application/Channels/Commands/DeleteChannelHandler.cs

@ -39,7 +39,7 @@ public class DeleteChannelHandler : IRequestHandler<DeleteChannel, Either<BaseEr @@ -39,7 +39,7 @@ public class DeleteChannelHandler : IRequestHandler<DeleteChannel, Either<BaseEr
{
dbContext.Channels.Remove(channel);
await dbContext.SaveChangesAsync(cancellationToken);
_searchTargets.SearchTargetsChanged();
// delete channel data from channel guide cache

112
ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs

@ -22,9 +22,9 @@ namespace ErsatzTV.Application.Channels; @@ -22,9 +22,9 @@ namespace ErsatzTV.Application.Channels;
public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
private readonly IConfigElementRepository _configElementRepository;
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly ILocalFileSystem _localFileSystem;
private readonly IConfigElementRepository _configElementRepository;
private readonly ILogger<RefreshChannelDataHandler> _logger;
private readonly RecyclableMemoryStreamManager _recyclableMemoryStreamManager;
@ -45,7 +45,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -45,7 +45,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
public async Task Handle(RefreshChannelData request, CancellationToken cancellationToken)
{
_logger.LogDebug("Refreshing channel data (XMLTV) for channel {Channel}", request.ChannelNumber);
_localFileSystem.EnsureFolderExists(FileSystemLayout.ChannelGuideCacheFolder);
string movieTemplateFileName = GetMovieTemplateFileName();
@ -68,7 +68,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -68,7 +68,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
});
var templateContext = new XmlTemplateContext();
string movieText = await File.ReadAllTextAsync(movieTemplateFileName, cancellationToken);
var movieTemplate = Template.Parse(movieText, movieTemplateFileName);
@ -302,7 +302,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -302,7 +302,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
(_, true) => displayItem.GuideFinishOffset!.Value,
(_, false) => finishItem.FinishOffset
};
string start = startTime
.ToString("yyyyMMddHHmmss zzz", CultureInfo.InvariantCulture)
.Replace(":", string.Empty);
@ -329,7 +329,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -329,7 +329,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
i++;
}
}
private static async Task WriteBlockPlayoutXml(
RefreshChannelData request,
List<PlayoutItem> sorted,
@ -367,7 +367,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -367,7 +367,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
item,
start,
stop,
hasCustomTitle: false,
false,
templateContext,
movieTemplate,
episodeTemplate,
@ -481,7 +481,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -481,7 +481,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
metadata.Genres ??= [];
metadata.Guids ??= [];
string poster = Optional(metadata.Artwork).Flatten()
.Filter(a => a.ArtworkKind == ArtworkKind.Poster)
.HeadOrNone()
@ -491,9 +491,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -491,9 +491,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
ProgrammeStart = start,
ProgrammeStop = stop,
ChannelNumber = request.ChannelNumber,
request.ChannelNumber,
HasCustomTitle = hasCustomTitle,
CustomTitle = displayItem.CustomTitle,
displayItem.CustomTitle,
MovieTitle = title,
MovieHasPlot = !string.IsNullOrWhiteSpace(metadata.Plot),
MoviePlot = metadata.Plot,
@ -516,7 +516,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -516,7 +516,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
return Option<string>.None;
}
private static async Task<Option<string>> ProcessEpisodeTemplate(
RefreshChannelData request,
Episode templateEpisode,
@ -546,9 +546,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -546,9 +546,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
ProgrammeStart = start,
ProgrammeStop = stop,
ChannelNumber = request.ChannelNumber,
request.ChannelNumber,
HasCustomTitle = hasCustomTitle,
CustomTitle = displayItem.CustomTitle,
displayItem.CustomTitle,
ShowTitle = title,
EpisodeHasTitle = !string.IsNullOrWhiteSpace(subtitle),
EpisodeTitle = subtitle,
@ -560,13 +560,13 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -560,13 +560,13 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
EpisodeHasArtwork = !string.IsNullOrWhiteSpace(artworkPath),
EpisodeArtworkUrl = artworkPath,
SeasonNumber = templateEpisode.Season?.SeasonNumber ?? 0,
EpisodeNumber = metadata.EpisodeNumber,
metadata.EpisodeNumber,
ShowHasContentRating = !string.IsNullOrWhiteSpace(showMetadata.ContentRating),
ShowContentRating = showMetadata.ContentRating,
ShowGuids = showMetadata.Guids.Map(g => g.Guid),
EpisodeGuids = metadata.Guids.Map(g => g.Guid)
};
var scriptObject = new ScriptObject();
scriptObject.Import(data);
templateContext.PushGlobal(scriptObject);
@ -606,9 +606,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -606,9 +606,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
ProgrammeStart = start,
ProgrammeStop = stop,
ChannelNumber = request.ChannelNumber,
request.ChannelNumber,
HasCustomTitle = hasCustomTitle,
CustomTitle = displayItem.CustomTitle,
displayItem.CustomTitle,
ArtistTitle = title,
MusicVideoTitle = subtitle,
MusicVideoHasPlot = !string.IsNullOrWhiteSpace(metadata.Plot),
@ -639,7 +639,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -639,7 +639,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
return Option<string>.None;
}
private static async Task<Option<string>> ProcessSongTemplate(
RefreshChannelData request,
Song templateSong,
@ -663,9 +663,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -663,9 +663,9 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
ProgrammeStart = start,
ProgrammeStop = stop,
ChannelNumber = request.ChannelNumber,
request.ChannelNumber,
HasCustomTitle = hasCustomTitle,
CustomTitle = displayItem.CustomTitle,
displayItem.CustomTitle,
SongTitle = subtitle,
SongArtists = metadata.Artists,
SongAlbumArtists = metadata.AlbumArtists,
@ -682,7 +682,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -682,7 +682,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
SongAlbum = metadata.Album,
SongHasReleaseDate = metadata.ReleaseDate.HasValue,
SongReleaseDate = metadata.ReleaseDate,
SongStudios = metadata.Studios.Map(s => s.Name),
SongStudios = metadata.Studios.Map(s => s.Name)
};
var scriptObject = new ScriptObject();
@ -694,7 +694,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -694,7 +694,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
return Option<string>.None;
}
private static async Task<Option<string>> ProcessOtherVideoTemplate(
RefreshChannelData request,
OtherVideo templateOtherVideo,
@ -710,14 +710,14 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -710,14 +710,14 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
metadata.Genres ??= [];
metadata.Guids ??= [];
var data = new
{
ProgrammeStart = start,
ProgrammeStop = stop,
ChannelNumber = request.ChannelNumber,
request.ChannelNumber,
HasCustomTitle = hasCustomTitle,
CustomTitle = displayItem.CustomTitle,
displayItem.CustomTitle,
OtherVideoTitle = title,
OtherVideoHasPlot = !string.IsNullOrWhiteSpace(metadata.Plot),
OtherVideoPlot = metadata.Plot,
@ -741,13 +741,13 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -741,13 +741,13 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
private string GetMovieTemplateFileName()
{
string templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "movie.sbntxt");
// fall back to default template
if (!_localFileSystem.FileExists(templateFileName))
{
templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "_movie.sbntxt");
}
// fail if file doesn't exist
if (!_localFileSystem.FileExists(templateFileName))
{
@ -760,17 +760,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -760,17 +760,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
return templateFileName;
}
private string GetEpisodeTemplateFileName()
{
string templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "episode.sbntxt");
// fall back to default template
if (!_localFileSystem.FileExists(templateFileName))
{
templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "_episode.sbntxt");
}
// fail if file doesn't exist
if (!_localFileSystem.FileExists(templateFileName))
{
@ -783,17 +783,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -783,17 +783,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
return templateFileName;
}
private string GetMusicVideoTemplateFileName()
{
string templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "musicVideo.sbntxt");
// fall back to default template
if (!_localFileSystem.FileExists(templateFileName))
{
templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "_musicVideo.sbntxt");
}
// fail if file doesn't exist
if (!_localFileSystem.FileExists(templateFileName))
{
@ -806,17 +806,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -806,17 +806,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
return templateFileName;
}
private string GetSongTemplateFileName()
{
string templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "song.sbntxt");
// fall back to default template
if (!_localFileSystem.FileExists(templateFileName))
{
templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "_song.sbntxt");
}
// fail if file doesn't exist
if (!_localFileSystem.FileExists(templateFileName))
{
@ -829,17 +829,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -829,17 +829,17 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
return templateFileName;
}
private string GetOtherVideoTemplateFileName()
{
string templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "otherVideo.sbntxt");
// fall back to default template
if (!_localFileSystem.FileExists(templateFileName))
{
templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "_otherVideo.sbntxt");
}
// fail if file doesn't exist
if (!_localFileSystem.FileExists(templateFileName))
{
@ -863,10 +863,12 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -863,10 +863,12 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
_ => 440
};
if (artworkPath.StartsWith("http://", StringComparison.OrdinalIgnoreCase) || artworkPath.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
if (artworkPath.StartsWith("http://", StringComparison.OrdinalIgnoreCase) ||
artworkPath.StartsWith("https://", StringComparison.OrdinalIgnoreCase))
{
return artworkPath;
}
if (artworkPath.StartsWith("jellyfin://", StringComparison.OrdinalIgnoreCase))
{
artworkPath = JellyfinUrl.PlaceholderProxyForArtwork(artworkPath, artworkKind, height);
@ -1025,7 +1027,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -1025,7 +1027,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
foreach (ExternalJsonChannel channel in maybeChannel)
{
// TODO: null start time should log and throw
DateTimeOffset startTime = DateTimeOffset.Parse(
channel.StartTime ?? string.Empty,
CultureInfo.InvariantCulture,
@ -1077,14 +1079,15 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -1077,14 +1079,15 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
var artwork = new List<Artwork>();
if (!string.IsNullOrWhiteSpace(program.Icon))
{
artwork.Add(new Artwork
{
ArtworkKind = ArtworkKind.Thumbnail,
Path = program.Icon,
SourcePath = program.Icon
});
artwork.Add(
new Artwork
{
ArtworkKind = ArtworkKind.Thumbnail,
Path = program.Icon,
SourcePath = program.Icon
});
}
return new Episode
{
MediaVersions =
@ -1100,7 +1103,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -1100,7 +1103,7 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
{
EpisodeNumber = program.Episode,
Title = program.Title
},
}
],
Season = new Season
{
@ -1125,12 +1128,13 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -1125,12 +1128,13 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
var artwork = new List<Artwork>();
if (!string.IsNullOrWhiteSpace(program.Icon))
{
artwork.Add(new Artwork
{
ArtworkKind = ArtworkKind.Poster,
Path = program.Icon,
SourcePath = program.Icon
});
artwork.Add(
new Artwork
{
ArtworkKind = ArtworkKind.Poster,
Path = program.Icon,
SourcePath = program.Icon
});
}
return new Movie

10
ErsatzTV.Application/Channels/Commands/RefreshChannelListHandler.cs

@ -39,13 +39,13 @@ public class RefreshChannelListHandler : IRequestHandler<RefreshChannelList> @@ -39,13 +39,13 @@ public class RefreshChannelListHandler : IRequestHandler<RefreshChannelList>
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
string templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "channel.sbntxt");
// fall back to default template
if (!_localFileSystem.FileExists(templateFileName))
{
templateFileName = Path.Combine(FileSystemLayout.ChannelGuideTemplatesFolder, "_channel.sbntxt");
}
// fail if file doesn't exist
if (!_localFileSystem.FileExists(templateFileName))
{
@ -63,11 +63,11 @@ public class RefreshChannelListHandler : IRequestHandler<RefreshChannelList> @@ -63,11 +63,11 @@ public class RefreshChannelListHandler : IRequestHandler<RefreshChannelList>
RemoveXmlComments = true,
CollapseTagsWithoutContent = true
});
string text = await File.ReadAllTextAsync(templateFileName, cancellationToken);
var template = Template.Parse(text, templateFileName);
var templateContext = new XmlTemplateContext();
await using RecyclableMemoryStream ms = _recyclableMemoryStreamManager.GetStream();
await using var xml = XmlWriter.Create(
ms,
@ -83,7 +83,7 @@ public class RefreshChannelListHandler : IRequestHandler<RefreshChannelList> @@ -83,7 +83,7 @@ public class RefreshChannelListHandler : IRequestHandler<RefreshChannelList>
ChannelHasArtwork = !string.IsNullOrWhiteSpace(channel.ArtworkPath),
ChannelArtworkPath = channel.ArtworkPath
};
var scriptObject = new ScriptObject();
scriptObject.Import(data);
templateContext.PushGlobal(scriptObject);

3
ErsatzTV.Application/Channels/Commands/UpdateChannel.cs

@ -3,8 +3,7 @@ using ErsatzTV.Core.Domain; @@ -3,8 +3,7 @@ using ErsatzTV.Core.Domain;
namespace ErsatzTV.Application.Channels;
public record UpdateChannel
(
public record UpdateChannel(
int ChannelId,
string Name,
string Number,

4
ErsatzTV.Application/Channels/Commands/UpdateChannelHandler.cs

@ -71,7 +71,7 @@ public class UpdateChannelHandler( @@ -71,7 +71,7 @@ public class UpdateChannelHandler(
c.WatermarkId = update.WatermarkId;
c.FallbackFillerId = update.FallbackFillerId;
await dbContext.SaveChangesAsync();
searchTargets.SearchTargetsChanged();
if (c.SubtitleMode != ChannelSubtitleMode.None)
@ -84,7 +84,7 @@ public class UpdateChannelHandler( @@ -84,7 +84,7 @@ public class UpdateChannelHandler(
await workerChannel.WriteAsync(new ExtractEmbeddedSubtitles(playout.Id));
}
}
await workerChannel.WriteAsync(new RefreshChannelList());
return ProjectToViewModel(c);

4
ErsatzTV.Application/Channels/Queries/GetChannelGuide.cs

@ -3,5 +3,5 @@ using ErsatzTV.Core.Iptv; @@ -3,5 +3,5 @@ using ErsatzTV.Core.Iptv;
namespace ErsatzTV.Application.Channels;
public record GetChannelGuide
(string Scheme, string Host, string BaseUrl, string AccessToken) : IRequest<Either<BaseError, ChannelGuide>>;
public record GetChannelGuide(string Scheme, string Host, string BaseUrl, string AccessToken)
: IRequest<Either<BaseError, ChannelGuide>>;

18
ErsatzTV.Application/Configuration/Commands/UpdateGeneralSettingsHandler.cs

@ -26,16 +26,24 @@ public class UpdateGeneralSettingsHandler : IRequestHandler<UpdateGeneralSetting @@ -26,16 +26,24 @@ public class UpdateGeneralSettingsHandler : IRequestHandler<UpdateGeneralSetting
await _configElementRepository.Upsert(ConfigElementKey.MinimumLogLevel, generalSettings.DefaultMinimumLogLevel);
_loggingLevelSwitches.DefaultLevelSwitch.MinimumLevel = generalSettings.DefaultMinimumLogLevel;
await _configElementRepository.Upsert(ConfigElementKey.MinimumLogLevelScanning, generalSettings.ScanningMinimumLogLevel);
await _configElementRepository.Upsert(
ConfigElementKey.MinimumLogLevelScanning,
generalSettings.ScanningMinimumLogLevel);
_loggingLevelSwitches.ScanningLevelSwitch.MinimumLevel = generalSettings.ScanningMinimumLogLevel;
await _configElementRepository.Upsert(ConfigElementKey.MinimumLogLevelScheduling, generalSettings.SchedulingMinimumLogLevel);
await _configElementRepository.Upsert(
ConfigElementKey.MinimumLogLevelScheduling,
generalSettings.SchedulingMinimumLogLevel);
_loggingLevelSwitches.SchedulingLevelSwitch.MinimumLevel = generalSettings.SchedulingMinimumLogLevel;
await _configElementRepository.Upsert(ConfigElementKey.MinimumLogLevelStreaming, generalSettings.StreamingMinimumLogLevel);
await _configElementRepository.Upsert(
ConfigElementKey.MinimumLogLevelStreaming,
generalSettings.StreamingMinimumLogLevel);
_loggingLevelSwitches.StreamingLevelSwitch.MinimumLevel = generalSettings.StreamingMinimumLogLevel;
await _configElementRepository.Upsert(ConfigElementKey.MinimumLogLevelHttp, generalSettings.HttpMinimumLogLevel);
await _configElementRepository.Upsert(
ConfigElementKey.MinimumLogLevelHttp,
generalSettings.HttpMinimumLogLevel);
_loggingLevelSwitches.HttpLevelSwitch.MinimumLevel = generalSettings.HttpMinimumLogLevel;
return Unit.Default;

2
ErsatzTV.Application/Configuration/Commands/UpdateXmltvSettingsHandler.cs

@ -31,4 +31,4 @@ public class UpdateXmltvSettingsHandler( @@ -31,4 +31,4 @@ public class UpdateXmltvSettingsHandler(
return Unit.Default;
}
}
}

6
ErsatzTV.Application/Configuration/Queries/GetGeneralSettingsHandler.cs

@ -15,16 +15,16 @@ public class GetGeneralSettingsHandler : IRequestHandler<GetGeneralSettings, Gen @@ -15,16 +15,16 @@ public class GetGeneralSettingsHandler : IRequestHandler<GetGeneralSettings, Gen
{
Option<LogEventLevel> maybeDefaultLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevel);
Option<LogEventLevel> maybeScanningLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelScanning);
Option<LogEventLevel> maybeSchedulingLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelScheduling);
Option<LogEventLevel> maybeStreamingLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelStreaming);
Option<LogEventLevel> maybeHttpLevel =
await _configElementRepository.GetValue<LogEventLevel>(ConfigElementKey.MinimumLogLevelHttp);

3
ErsatzTV.Application/Emby/Commands/UpdateEmbyLibraryPreferences.cs

@ -2,7 +2,6 @@ @@ -2,7 +2,6 @@
namespace ErsatzTV.Application.Emby;
public record UpdateEmbyLibraryPreferences
(List<EmbyLibraryPreference> Preferences) : IRequest<Either<BaseError, Unit>>;
public record UpdateEmbyLibraryPreferences(List<EmbyLibraryPreference> Preferences) : IRequest<Either<BaseError, Unit>>;
public record EmbyLibraryPreference(int Id, bool ShouldSyncItems);

2
ErsatzTV.Application/Emby/Commands/UpdateEmbyLibraryPreferencesHandler.cs

@ -6,7 +6,7 @@ namespace ErsatzTV.Application.Emby; @@ -6,7 +6,7 @@ namespace ErsatzTV.Application.Emby;
public class
UpdateEmbyLibraryPreferencesHandler : IRequestHandler<UpdateEmbyLibraryPreferences,
Either<BaseError, Unit>>
Either<BaseError, Unit>>
{
private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly ISearchIndex _searchIndex;

10
ErsatzTV.Application/Emby/EmbyLibraryViewModel.cs

@ -4,9 +4,9 @@ using ErsatzTV.Core.Domain; @@ -4,9 +4,9 @@ using ErsatzTV.Core.Domain;
namespace ErsatzTV.Application.Emby;
public record EmbyLibraryViewModel(
int Id,
string Name,
LibraryMediaKind MediaKind,
bool ShouldSyncItems,
int MediaSourceId)
int Id,
string Name,
LibraryMediaKind MediaKind,
bool ShouldSyncItems,
int MediaSourceId)
: LibraryViewModel("Emby", Id, Name, MediaKind, MediaSourceId, string.Empty);

3
ErsatzTV.Application/Emby/Queries/GetEmbyPathReplacementsBySourceId.cs

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
namespace ErsatzTV.Application.Emby;
public record GetEmbyPathReplacementsBySourceId
(int EmbyMediaSourceId) : IRequest<List<EmbyPathReplacementViewModel>>;
public record GetEmbyPathReplacementsBySourceId(int EmbyMediaSourceId) : IRequest<List<EmbyPathReplacementViewModel>>;

4
ErsatzTV.Application/ErsatzTV.Application.csproj

@ -15,13 +15,13 @@ @@ -15,13 +15,13 @@
<PackageReference Include="MediatR" Version="12.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.8.14">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.9.28">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.Formatting.Compact.Reader" Version="3.0.0" />
<PackageReference Include="WebMarkupMin.Core" Version="2.14.0" />
<PackageReference Include="WebMarkupMin.Core" Version="2.16.0" />
<PackageReference Include="Winista.MimeDetect" Version="1.1.0" />
</ItemGroup>

3
ErsatzTV.Application/FFmpegProfiles/Commands/CopyFFmpegProfile.cs

@ -2,5 +2,4 @@ @@ -2,5 +2,4 @@
namespace ErsatzTV.Application.FFmpegProfiles;
public record CopyFFmpegProfile
(int FFmpegProfileId, string Name) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;
public record CopyFFmpegProfile(int FFmpegProfileId, string Name) : IRequest<Either<BaseError, FFmpegProfileViewModel>>;

4
ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegProfileHandler.cs

@ -59,9 +59,9 @@ public class @@ -59,9 +59,9 @@ public class
p.NormalizeFramerate = update.NormalizeFramerate;
p.DeinterlaceVideo = update.DeinterlaceVideo;
await dbContext.SaveChangesAsync();
_searchTargets.SearchTargetsChanged();
return new UpdateFFmpegProfileResult(p.Id);
}

4
ErsatzTV.Application/FFmpegProfiles/Commands/UpdateFFmpegSettingsHandler.cs

@ -101,11 +101,11 @@ public class UpdateFFmpegSettingsHandler : IRequestHandler<UpdateFFmpegSettings, @@ -101,11 +101,11 @@ public class UpdateFFmpegSettingsHandler : IRequestHandler<UpdateFFmpegSettings,
{
request.Settings.ExtractEmbeddedSubtitles = false;
}
await _configElementRepository.Upsert(
ConfigElementKey.FFmpegExtractEmbeddedSubtitles,
request.Settings.ExtractEmbeddedSubtitles);
// queue extracting all embedded subtitles
if (request.Settings.ExtractEmbeddedSubtitles)
{

2
ErsatzTV.Application/FFmpegProfiles/Queries/GetFFmpegProfileByIdForApiHandler.cs

@ -8,7 +8,7 @@ namespace ErsatzTV.Application.FFmpegProfiles; @@ -8,7 +8,7 @@ namespace ErsatzTV.Application.FFmpegProfiles;
public class
GetFFmpegProfileByIdForApiHandler : IRequestHandler<GetFFmpegFullProfileByIdForApi,
Option<FFmpegFullProfileResponseModel>>
Option<FFmpegFullProfileResponseModel>>
{
private readonly IDbContextFactory<TvContext> _dbContextFactory;

2
ErsatzTV.Application/FFmpegProfiles/Queries/GetSupportedHardwareAccelerationKindsHandler.cs

@ -10,7 +10,7 @@ namespace ErsatzTV.Application.FFmpegProfiles; @@ -10,7 +10,7 @@ namespace ErsatzTV.Application.FFmpegProfiles;
public class
GetSupportedHardwareAccelerationKindsHandler : IRequestHandler<GetSupportedHardwareAccelerationKinds,
List<HardwareAccelerationKind>>
List<HardwareAccelerationKind>>
{
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly IHardwareCapabilitiesFactory _hardwareCapabilitiesFactory;

12
ErsatzTV.Application/Images/Commands/UpdateImageFolderDurationHandler.cs

@ -16,7 +16,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon @@ -16,7 +16,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon
{
request = request with { ImageFolderDuration = 0.01 };
}
// delete entry if null
if (request.ImageFolderDuration is null)
{
@ -48,7 +48,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon @@ -48,7 +48,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon
await dbContext.SaveChangesAsync(cancellationToken);
}
}
// update all images (bfs) starting at this folder
Option<LibraryFolder> maybeFolder = await dbContext.LibraryFolders
.AsNoTracking()
@ -59,7 +59,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon @@ -59,7 +59,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon
foreach (LibraryFolder libraryFolder in maybeFolder)
{
LibraryFolder currentFolder = libraryFolder;
// walk up to get duration, if needed
double? durationSeconds = currentFolder.ImageFolderDuration?.DurationSeconds;
while (durationSeconds is null && currentFolder?.ParentId is not null)
@ -73,7 +73,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon @@ -73,7 +73,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon
{
currentFolder = null;
}
foreach (LibraryFolder parent in maybeParent)
{
currentFolder = parent;
@ -83,7 +83,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon @@ -83,7 +83,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon
queue.Enqueue(new FolderWithParentDuration(libraryFolder, durationSeconds));
}
while (queue.Count > 0)
{
(LibraryFolder currentFolder, double? parentDuration) = queue.Dequeue();
@ -109,7 +109,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon @@ -109,7 +109,7 @@ public class UpdateImageFolderDurationHandler(IDbContextFactory<TvContext> dbCon
.Filter(lf => lf.ParentId == currentFolder.Id)
.Include(lf => lf.ImageFolderDuration)
.ToListAsync(cancellationToken);
// queue all children
foreach (LibraryFolder child in children)
{

5
ErsatzTV.Application/Images/Queries/GetCachedImagePath.cs

@ -3,6 +3,5 @@ using ErsatzTV.Core.Domain; @@ -3,6 +3,5 @@ using ErsatzTV.Core.Domain;
namespace ErsatzTV.Application.Images;
public record GetCachedImagePath
(string FileName, ArtworkKind ArtworkKind, int? MaxHeight = null) : IRequest<
Either<BaseError, CachedImagePathViewModel>>;
public record GetCachedImagePath(string FileName, ArtworkKind ArtworkKind, int? MaxHeight = null) : IRequest<
Either<BaseError, CachedImagePathViewModel>>;

2
ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinAdminUserIdHandler.cs

@ -10,7 +10,7 @@ namespace ErsatzTV.Application.Jellyfin; @@ -10,7 +10,7 @@ namespace ErsatzTV.Application.Jellyfin;
public class
SynchronizeJellyfinAdminUserIdHandler : IRequestHandler<SynchronizeJellyfinAdminUserId,
Either<BaseError, Unit>>
Either<BaseError, Unit>>
{
private readonly IJellyfinApiClient _jellyfinApiClient;
private readonly IJellyfinSecretStore _jellyfinSecretStore;

4
ErsatzTV.Application/Jellyfin/Commands/SynchronizeJellyfinLibraryById.cs

@ -16,8 +16,8 @@ public record SynchronizeJellyfinLibraryByIdIfNeeded(int JellyfinLibraryId) : IS @@ -16,8 +16,8 @@ public record SynchronizeJellyfinLibraryByIdIfNeeded(int JellyfinLibraryId) : IS
public bool DeepScan => false;
}
public record ForceSynchronizeJellyfinLibraryById
(int JellyfinLibraryId, bool DeepScan) : ISynchronizeJellyfinLibraryById
public record ForceSynchronizeJellyfinLibraryById(int JellyfinLibraryId, bool DeepScan)
: ISynchronizeJellyfinLibraryById
{
public bool ForceScan => true;
}

4
ErsatzTV.Application/Jellyfin/Commands/UpdateJellyfinLibraryPreferences.cs

@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
namespace ErsatzTV.Application.Jellyfin;
public record UpdateJellyfinLibraryPreferences
(List<JellyfinLibraryPreference> Preferences) : IRequest<Either<BaseError, Unit>>;
public record UpdateJellyfinLibraryPreferences(List<JellyfinLibraryPreference> Preferences)
: IRequest<Either<BaseError, Unit>>;
public record JellyfinLibraryPreference(int Id, bool ShouldSyncItems);

2
ErsatzTV.Application/Jellyfin/Commands/UpdateJellyfinLibraryPreferencesHandler.cs

@ -6,7 +6,7 @@ namespace ErsatzTV.Application.Jellyfin; @@ -6,7 +6,7 @@ namespace ErsatzTV.Application.Jellyfin;
public class
UpdateJellyfinLibraryPreferencesHandler : IRequestHandler<UpdateJellyfinLibraryPreferences,
Either<BaseError, Unit>>
Either<BaseError, Unit>>
{
private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly ISearchIndex _searchIndex;

10
ErsatzTV.Application/Jellyfin/JellyfinLibraryViewModel.cs

@ -4,9 +4,9 @@ using ErsatzTV.Core.Domain; @@ -4,9 +4,9 @@ using ErsatzTV.Core.Domain;
namespace ErsatzTV.Application.Jellyfin;
public record JellyfinLibraryViewModel(
int Id,
string Name,
LibraryMediaKind MediaKind,
bool ShouldSyncItems,
int MediaSourceId)
int Id,
string Name,
LibraryMediaKind MediaKind,
bool ShouldSyncItems,
int MediaSourceId)
: LibraryViewModel("Jellyfin", Id, Name, MediaKind, MediaSourceId, string.Empty);

2
ErsatzTV.Application/Jellyfin/Queries/GetAllJellyfinMediaSourcesHandler.cs

@ -5,7 +5,7 @@ namespace ErsatzTV.Application.Jellyfin; @@ -5,7 +5,7 @@ namespace ErsatzTV.Application.Jellyfin;
public class
GetAllJellyfinMediaSourcesHandler : IRequestHandler<GetAllJellyfinMediaSources,
List<JellyfinMediaSourceViewModel>>
List<JellyfinMediaSourceViewModel>>
{
private readonly IMediaSourceRepository _mediaSourceRepository;

2
ErsatzTV.Application/Jellyfin/Queries/GetJellyfinLibrariesBySourceIdHandler.cs

@ -5,7 +5,7 @@ namespace ErsatzTV.Application.Jellyfin; @@ -5,7 +5,7 @@ namespace ErsatzTV.Application.Jellyfin;
public class
GetJellyfinLibrariesBySourceIdHandler : IRequestHandler<GetJellyfinLibrariesBySourceId,
List<JellyfinLibraryViewModel>>
List<JellyfinLibraryViewModel>>
{
private readonly IMediaSourceRepository _mediaSourceRepository;

3
ErsatzTV.Application/Jellyfin/Queries/GetJellyfinMediaSourceById.cs

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
namespace ErsatzTV.Application.Jellyfin;
public record GetJellyfinMediaSourceById
(int JellyfinMediaSourceId) : IRequest<Option<JellyfinMediaSourceViewModel>>;
public record GetJellyfinMediaSourceById(int JellyfinMediaSourceId) : IRequest<Option<JellyfinMediaSourceViewModel>>;

2
ErsatzTV.Application/Jellyfin/Queries/GetJellyfinMediaSourceByIdHandler.cs

@ -5,7 +5,7 @@ namespace ErsatzTV.Application.Jellyfin; @@ -5,7 +5,7 @@ namespace ErsatzTV.Application.Jellyfin;
public class
GetJellyfinMediaSourceByIdHandler : IRequestHandler<GetJellyfinMediaSourceById,
Option<JellyfinMediaSourceViewModel>>
Option<JellyfinMediaSourceViewModel>>
{
private readonly IMediaSourceRepository _mediaSourceRepository;

4
ErsatzTV.Application/Jellyfin/Queries/GetJellyfinPathReplacementsBySourceId.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
namespace ErsatzTV.Application.Jellyfin;
public record GetJellyfinPathReplacementsBySourceId
(int JellyfinMediaSourceId) : IRequest<List<JellyfinPathReplacementViewModel>>;
public record GetJellyfinPathReplacementsBySourceId(int JellyfinMediaSourceId)
: IRequest<List<JellyfinPathReplacementViewModel>>;

11
ErsatzTV.Application/Libraries/Commands/CallLibraryScannerHandler.cs

@ -13,6 +13,7 @@ using ErsatzTV.Infrastructure.Data; @@ -13,6 +13,7 @@ using ErsatzTV.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using Serilog;
using Serilog.Core;
using Serilog.Events;
using Serilog.Formatting.Compact.Reader;
@ -20,6 +21,7 @@ namespace ErsatzTV.Application.Libraries; @@ -20,6 +21,7 @@ namespace ErsatzTV.Application.Libraries;
public abstract class CallLibraryScannerHandler<TRequest>
{
private readonly int _batchSize = 100;
private readonly ChannelWriter<ISearchIndexBackgroundServiceRequest> _channel;
private readonly IConfigElementRepository _configElementRepository;
private readonly IDbContextFactory<TvContext> _dbContextFactory;
@ -27,7 +29,6 @@ public abstract class CallLibraryScannerHandler<TRequest> @@ -27,7 +29,6 @@ public abstract class CallLibraryScannerHandler<TRequest>
private readonly IRuntimeInfo _runtimeInfo;
private readonly List<int> _toReindex = [];
private readonly List<int> _toRemove = [];
private readonly int _batchSize = 100;
private string _libraryName;
protected CallLibraryScannerHandler(
@ -74,7 +75,7 @@ public abstract class CallLibraryScannerHandler<TRequest> @@ -74,7 +75,7 @@ public abstract class CallLibraryScannerHandler<TRequest>
await _channel.WriteAsync(new ReindexMediaItems(_toReindex.ToArray()), cancellationToken);
_toReindex.Clear();
}
if (_toRemove.Count > 0)
{
await _channel.WriteAsync(new RemoveMediaItems(_toReindex.ToArray()), cancellationToken);
@ -104,10 +105,10 @@ public abstract class CallLibraryScannerHandler<TRequest> @@ -104,10 +105,10 @@ public abstract class CallLibraryScannerHandler<TRequest>
if (logEvent.Properties.TryGetValue("SourceContext", out LogEventPropertyValue property))
{
log = log.ForContext(
Serilog.Core.Constants.SourceContextPropertyName,
Constants.SourceContextPropertyName,
property.ToString().Trim('"'));
}
log.Write(
new LogEvent(
logEvent.Timestamp.ToLocalTime(),
@ -143,7 +144,7 @@ public abstract class CallLibraryScannerHandler<TRequest> @@ -143,7 +144,7 @@ public abstract class CallLibraryScannerHandler<TRequest>
await _channel.WriteAsync(new ReindexMediaItems(_toReindex.ToArray()));
_toReindex.Clear();
}
_toRemove.AddRange(progressUpdate.ItemsToRemove);
if (_toRemove.Count >= _batchSize)
{

2
ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryHandler.cs

@ -32,7 +32,7 @@ public class CreateLocalLibraryHandler : LocalLibraryHandlerBase, @@ -32,7 +32,7 @@ public class CreateLocalLibraryHandler : LocalLibraryHandlerBase,
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, LocalLibrary> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, localLibrary => PersistLocalLibrary(dbContext, localLibrary));
return await validation.Apply(localLibrary => PersistLocalLibrary(dbContext, localLibrary));
}
private async Task<LocalLibraryViewModel> PersistLocalLibrary(

4
ErsatzTV.Application/Libraries/Commands/CreateLocalLibraryPath.cs

@ -2,5 +2,5 @@ @@ -2,5 +2,5 @@
namespace ErsatzTV.Application.Libraries;
public record CreateLocalLibraryPath
(int LibraryId, string Path) : IRequest<Either<BaseError, LocalLibraryPathViewModel>>;
public record CreateLocalLibraryPath(int LibraryId, string Path)
: IRequest<Either<BaseError, LocalLibraryPathViewModel>>;

2
ErsatzTV.Application/Libraries/Commands/DeleteLocalLibraryHandler.cs

@ -28,7 +28,7 @@ public class DeleteLocalLibraryHandler : LocalLibraryHandlerBase, @@ -28,7 +28,7 @@ public class DeleteLocalLibraryHandler : LocalLibraryHandlerBase,
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, LocalLibrary> validation = await LocalLibraryMustExist(dbContext, request);
return await LanguageExtensions.Apply(validation, localLibrary => DoDeletion(dbContext, localLibrary));
return await validation.Apply(localLibrary => DoDeletion(dbContext, localLibrary));
}
private async Task<Unit> DoDeletion(TvContext dbContext, LocalLibrary localLibrary)

2
ErsatzTV.Application/Libraries/Commands/MoveLocalLibraryPathHandler.cs

@ -39,7 +39,7 @@ public class MoveLocalLibraryPathHandler : IRequestHandler<MoveLocalLibraryPath, @@ -39,7 +39,7 @@ public class MoveLocalLibraryPathHandler : IRequestHandler<MoveLocalLibraryPath,
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, parameters => MovePath(dbContext, parameters));
return await validation.Apply(parameters => MovePath(dbContext, parameters));
}
private async Task<Unit> MovePath(TvContext dbContext, Parameters parameters)

2
ErsatzTV.Application/Libraries/Commands/UpdateLocalLibraryHandler.cs

@ -37,7 +37,7 @@ public class UpdateLocalLibraryHandler : LocalLibraryHandlerBase, @@ -37,7 +37,7 @@ public class UpdateLocalLibraryHandler : LocalLibraryHandlerBase,
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, parameters => UpdateLocalLibrary(dbContext, parameters));
return await validation.Apply(parameters => UpdateLocalLibrary(dbContext, parameters));
}
private async Task<LocalLibraryViewModel> UpdateLocalLibrary(TvContext dbContext, Parameters parameters)

10
ErsatzTV.Application/Libraries/PlexLibraryViewModel.cs

@ -3,9 +3,9 @@ @@ -3,9 +3,9 @@
namespace ErsatzTV.Application.Libraries;
public record PlexLibraryViewModel(
int Id,
string Name,
LibraryMediaKind MediaKind,
int MediaSourceId,
string MediaSourceName)
int Id,
string Name,
LibraryMediaKind MediaKind,
int MediaSourceId,
string MediaSourceName)
: LibraryViewModel("Plex", Id, Name, MediaKind, MediaSourceId, MediaSourceName);

3
ErsatzTV.Application/MediaCards/ArtistCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record ArtistCardViewModel
(
public record ArtistCardViewModel(
int ArtistId,
string Title,
string Subtitle,

3
ErsatzTV.Application/MediaCards/ImageCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record ImageCardViewModel
(
public record ImageCardViewModel(
int ImageId,
string Title,
string Subtitle,

3
ErsatzTV.Application/MediaCards/MovieCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record MovieCardViewModel
(
public record MovieCardViewModel(
int MovieId,
string Title,
string Subtitle,

3
ErsatzTV.Application/MediaCards/MusicVideoCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record MusicVideoCardViewModel
(
public record MusicVideoCardViewModel(
int MusicVideoId,
string Title,
string Subtitle,

3
ErsatzTV.Application/MediaCards/OtherVideoCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record OtherVideoCardViewModel
(
public record OtherVideoCardViewModel(
int OtherVideoId,
string Title,
string Subtitle,

3
ErsatzTV.Application/MediaCards/Queries/GetMusicVideoCards.cs

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
namespace ErsatzTV.Application.MediaCards;
public record GetMusicVideoCards
(int ArtistId, int PageNumber, int PageSize) : IRequest<MusicVideoCardResultsViewModel>;
public record GetMusicVideoCards(int ArtistId, int PageNumber, int PageSize) : IRequest<MusicVideoCardResultsViewModel>;

4
ErsatzTV.Application/MediaCards/Queries/GetTelevisionEpisodeCards.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
namespace ErsatzTV.Application.MediaCards;
public record GetTelevisionEpisodeCards
(int TelevisionSeasonId, int PageNumber, int PageSize) : IRequest<TelevisionEpisodeCardResultsViewModel>;
public record GetTelevisionEpisodeCards(int TelevisionSeasonId, int PageNumber, int PageSize)
: IRequest<TelevisionEpisodeCardResultsViewModel>;

4
ErsatzTV.Application/MediaCards/Queries/GetTelevisionSeasonCards.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
namespace ErsatzTV.Application.MediaCards;
public record GetTelevisionSeasonCards
(int TelevisionShowId, int PageNumber, int PageSize) : IRequest<TelevisionSeasonCardResultsViewModel>;
public record GetTelevisionSeasonCards(int TelevisionShowId, int PageNumber, int PageSize)
: IRequest<TelevisionSeasonCardResultsViewModel>;

2
ErsatzTV.Application/MediaCards/Queries/GetTelevisionSeasonCardsHandler.cs

@ -6,7 +6,7 @@ namespace ErsatzTV.Application.MediaCards; @@ -6,7 +6,7 @@ namespace ErsatzTV.Application.MediaCards;
public class
GetTelevisionSeasonCardsHandler : IRequestHandler<GetTelevisionSeasonCards,
TelevisionSeasonCardResultsViewModel>
TelevisionSeasonCardResultsViewModel>
{
private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly ITelevisionRepository _televisionRepository;

3
ErsatzTV.Application/MediaCards/SongCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record SongCardViewModel
(
public record SongCardViewModel(
int SongId,
string Title,
string Subtitle,

3
ErsatzTV.Application/MediaCards/TelevisionEpisodeCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record TelevisionEpisodeCardViewModel
(
public record TelevisionEpisodeCardViewModel(
int EpisodeId,
DateTime Aired,
string ShowTitle,

3
ErsatzTV.Application/MediaCards/TelevisionSeasonCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record TelevisionSeasonCardViewModel
(
public record TelevisionSeasonCardViewModel(
string ShowTitle,
int TelevisionSeasonId,
int TelevisionSeasonNumber,

3
ErsatzTV.Application/MediaCards/TelevisionShowCardViewModel.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCards;
public record TelevisionShowCardViewModel
(
public record TelevisionShowCardViewModel(
int TelevisionShowId,
string Title,
string Subtitle,

3
ErsatzTV.Application/MediaCollections/Commands/AddArtistToCollection.cs

@ -2,5 +2,4 @@ @@ -2,5 +2,4 @@
namespace ErsatzTV.Application.MediaCollections;
public record AddArtistToCollection
(int CollectionId, int ArtistId) : IRequest<Either<BaseError, Unit>>;
public record AddArtistToCollection(int CollectionId, int ArtistId) : IRequest<Either<BaseError, Unit>>;

2
ErsatzTV.Application/MediaCollections/Commands/AddArtistToCollectionHandler.cs

@ -33,7 +33,7 @@ public class AddArtistToCollectionHandler : @@ -33,7 +33,7 @@ public class AddArtistToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, parameters => ApplyAddArtistRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddArtistRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddArtistRequest(TvContext dbContext, Parameters parameters)

4
ErsatzTV.Application/MediaCollections/Commands/AddEpisodeToCollectionHandler.cs

@ -33,9 +33,7 @@ public class AddEpisodeToCollectionHandler : @@ -33,9 +33,7 @@ public class AddEpisodeToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(
validation,
parameters => ApplyAddTelevisionEpisodeRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddTelevisionEpisodeRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddTelevisionEpisodeRequest(TvContext dbContext, Parameters parameters)

3
ErsatzTV.Application/MediaCollections/Commands/AddItemsToCollection.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCollections;
public record AddItemsToCollection
(
public record AddItemsToCollection(
int CollectionId,
List<int> MovieIds,
List<int> ShowIds,

2
ErsatzTV.Application/MediaCollections/Commands/AddMovieToCollectionHandler.cs

@ -33,7 +33,7 @@ public class AddMovieToCollectionHandler : @@ -33,7 +33,7 @@ public class AddMovieToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, parameters => ApplyAddMovieRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddMovieRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddMovieRequest(TvContext dbContext, Parameters parameters)

3
ErsatzTV.Application/MediaCollections/Commands/AddMusicVideoToCollection.cs

@ -2,5 +2,4 @@ @@ -2,5 +2,4 @@
namespace ErsatzTV.Application.MediaCollections;
public record AddMusicVideoToCollection
(int CollectionId, int MusicVideoId) : IRequest<Either<BaseError, Unit>>;
public record AddMusicVideoToCollection(int CollectionId, int MusicVideoId) : IRequest<Either<BaseError, Unit>>;

4
ErsatzTV.Application/MediaCollections/Commands/AddMusicVideoToCollectionHandler.cs

@ -33,9 +33,7 @@ public class AddMusicVideoToCollectionHandler : @@ -33,9 +33,7 @@ public class AddMusicVideoToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(
validation,
parameters => ApplyAddMusicVideoRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddMusicVideoRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddMusicVideoRequest(TvContext dbContext, Parameters parameters)

3
ErsatzTV.Application/MediaCollections/Commands/AddOtherVideoToCollection.cs

@ -2,5 +2,4 @@ @@ -2,5 +2,4 @@
namespace ErsatzTV.Application.MediaCollections;
public record AddOtherVideoToCollection
(int CollectionId, int OtherVideoId) : IRequest<Either<BaseError, Unit>>;
public record AddOtherVideoToCollection(int CollectionId, int OtherVideoId) : IRequest<Either<BaseError, Unit>>;

4
ErsatzTV.Application/MediaCollections/Commands/AddOtherVideoToCollectionHandler.cs

@ -33,9 +33,7 @@ public class AddOtherVideoToCollectionHandler : @@ -33,9 +33,7 @@ public class AddOtherVideoToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(
validation,
parameters => ApplyAddOtherVideoRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddOtherVideoRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddOtherVideoRequest(TvContext dbContext, Parameters parameters)

2
ErsatzTV.Application/MediaCollections/Commands/AddSeasonToCollectionHandler.cs

@ -33,7 +33,7 @@ public class AddSeasonToCollectionHandler : @@ -33,7 +33,7 @@ public class AddSeasonToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, parameters => ApplyAddSeasonRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddSeasonRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddSeasonRequest(TvContext dbContext, Parameters parameters)

2
ErsatzTV.Application/MediaCollections/Commands/AddShowToCollectionHandler.cs

@ -33,7 +33,7 @@ public class AddShowToCollectionHandler : @@ -33,7 +33,7 @@ public class AddShowToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, parameters => ApplyAddShowRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddShowRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddShowRequest(TvContext dbContext, Parameters parameters)

3
ErsatzTV.Application/MediaCollections/Commands/AddSongToCollection.cs

@ -2,5 +2,4 @@ @@ -2,5 +2,4 @@
namespace ErsatzTV.Application.MediaCollections;
public record AddSongToCollection
(int CollectionId, int SongId) : IRequest<Either<BaseError, Unit>>;
public record AddSongToCollection(int CollectionId, int SongId) : IRequest<Either<BaseError, Unit>>;

2
ErsatzTV.Application/MediaCollections/Commands/AddSongToCollectionHandler.cs

@ -33,7 +33,7 @@ public class AddSongToCollectionHandler : @@ -33,7 +33,7 @@ public class AddSongToCollectionHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Parameters> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, parameters => ApplyAddSongRequest(dbContext, parameters));
return await validation.Apply(parameters => ApplyAddSongRequest(dbContext, parameters));
}
private async Task<Unit> ApplyAddSongRequest(TvContext dbContext, Parameters parameters)

4
ErsatzTV.Application/MediaCollections/Commands/CreateMultiCollection.cs

@ -9,5 +9,5 @@ public record CreateMultiCollectionItem( @@ -9,5 +9,5 @@ public record CreateMultiCollectionItem(
bool ScheduleAsGroup,
PlaybackOrder PlaybackOrder);
public record CreateMultiCollection
(string Name, List<CreateMultiCollectionItem> Items) : IRequest<Either<BaseError, MultiCollectionViewModel>>;
public record CreateMultiCollection(string Name, List<CreateMultiCollectionItem> Items)
: IRequest<Either<BaseError, MultiCollectionViewModel>>;

3
ErsatzTV.Application/MediaCollections/Commands/CreateSmartCollection.cs

@ -2,5 +2,4 @@ @@ -2,5 +2,4 @@
namespace ErsatzTV.Application.MediaCollections;
public record CreateSmartCollection
(string Query, string Name) : IRequest<Either<BaseError, SmartCollectionViewModel>>;
public record CreateSmartCollection(string Query, string Name) : IRequest<Either<BaseError, SmartCollectionViewModel>>;

2
ErsatzTV.Application/MediaCollections/Commands/DeleteTraktListHandler.cs

@ -44,7 +44,7 @@ public class DeleteTraktListHandler : TraktCommandBase, IRequestHandler<DeleteTr @@ -44,7 +44,7 @@ public class DeleteTraktListHandler : TraktCommandBase, IRequestHandler<DeleteTr
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, TraktList> validation = await TraktListMustExist(dbContext, request.TraktListId);
return await LanguageExtensions.Apply(validation, c => DoDeletion(dbContext, c));
return await validation.Apply(c => DoDeletion(dbContext, c));
}
finally
{

2
ErsatzTV.Application/MediaCollections/Commands/RemoveItemsFromCollectionHandler.cs

@ -32,7 +32,7 @@ public class RemoveItemsFromCollectionHandler : IRequestHandler<RemoveItemsFromC @@ -32,7 +32,7 @@ public class RemoveItemsFromCollectionHandler : IRequestHandler<RemoveItemsFromC
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Collection> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, c => ApplyRemoveItemsRequest(dbContext, request, c));
return await validation.Apply(c => ApplyRemoveItemsRequest(dbContext, request, c));
}
private async Task<Unit> ApplyRemoveItemsRequest(

3
ErsatzTV.Application/MediaCollections/Commands/UpdateCollection.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCollections;
public record UpdateCollection
(int CollectionId, string Name) : IRequest<Either<BaseError, Unit>>
public record UpdateCollection(int CollectionId, string Name) : IRequest<Either<BaseError, Unit>>
{
public Option<bool> UseCustomPlaybackOrder { get; set; } = None;
}

3
ErsatzTV.Application/MediaCollections/Commands/UpdateCollectionCustomOrder.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.MediaCollections;
public record UpdateCollectionCustomOrder
(
public record UpdateCollectionCustomOrder(
int CollectionId,
List<MediaItemCustomOrder> MediaItemCustomOrders) : IRequest<Either<BaseError, Unit>>;

2
ErsatzTV.Application/MediaCollections/Commands/UpdateCollectionCustomOrderHandler.cs

@ -32,7 +32,7 @@ public class UpdateCollectionCustomOrderHandler : IRequestHandler<UpdateCollecti @@ -32,7 +32,7 @@ public class UpdateCollectionCustomOrderHandler : IRequestHandler<UpdateCollecti
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Collection> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, c => ApplyUpdateRequest(dbContext, c, request));
return await validation.Apply(c => ApplyUpdateRequest(dbContext, c, request));
}
private async Task<Unit> ApplyUpdateRequest(

4
ErsatzTV.Application/MediaCollections/Commands/UpdateCollectionHandler.cs

@ -14,9 +14,9 @@ namespace ErsatzTV.Application.MediaCollections; @@ -14,9 +14,9 @@ namespace ErsatzTV.Application.MediaCollections;
public class UpdateCollectionHandler : IRequestHandler<UpdateCollection, Either<BaseError, Unit>>
{
private readonly ChannelWriter<IBackgroundServiceRequest> _channel;
private readonly ISearchTargets _searchTargets;
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly IMediaCollectionRepository _mediaCollectionRepository;
private readonly ISearchTargets _searchTargets;
public UpdateCollectionHandler(
IDbContextFactory<TvContext> dbContextFactory,
@ -56,7 +56,7 @@ public class UpdateCollectionHandler : IRequestHandler<UpdateCollection, Either< @@ -56,7 +56,7 @@ public class UpdateCollectionHandler : IRequestHandler<UpdateCollection, Either<
await _channel.WriteAsync(new BuildPlayout(playoutId, PlayoutBuildMode.Refresh));
}
}
_searchTargets.SearchTargetsChanged();
return Unit.Default;

3
ErsatzTV.Application/MediaCollections/Commands/UpdateMultiCollection.cs

@ -9,8 +9,7 @@ public record UpdateMultiCollectionItem( @@ -9,8 +9,7 @@ public record UpdateMultiCollectionItem(
bool ScheduleAsGroup,
PlaybackOrder PlaybackOrder);
public record UpdateMultiCollection
(
public record UpdateMultiCollection(
int MultiCollectionId,
string Name,
List<UpdateMultiCollectionItem> Items) : IRequest<Either<BaseError, Unit>>;

6
ErsatzTV.Application/MediaCollections/Commands/UpdateMultiCollectionHandler.cs

@ -14,9 +14,9 @@ namespace ErsatzTV.Application.MediaCollections; @@ -14,9 +14,9 @@ namespace ErsatzTV.Application.MediaCollections;
public class UpdateMultiCollectionHandler : IRequestHandler<UpdateMultiCollection, Either<BaseError, Unit>>
{
private readonly ChannelWriter<IBackgroundServiceRequest> _channel;
private readonly ISearchTargets _searchTargets;
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly IMediaCollectionRepository _mediaCollectionRepository;
private readonly ISearchTargets _searchTargets;
public UpdateMultiCollectionHandler(
IDbContextFactory<TvContext> dbContextFactory,
@ -36,7 +36,7 @@ public class UpdateMultiCollectionHandler : IRequestHandler<UpdateMultiCollectio @@ -36,7 +36,7 @@ public class UpdateMultiCollectionHandler : IRequestHandler<UpdateMultiCollectio
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, MultiCollection> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, c => ApplyUpdateRequest(dbContext, c, request));
return await validation.Apply(c => ApplyUpdateRequest(dbContext, c, request));
}
private async Task<Unit> ApplyUpdateRequest(TvContext dbContext, MultiCollection c, UpdateMultiCollection request)
@ -120,7 +120,7 @@ public class UpdateMultiCollectionHandler : IRequestHandler<UpdateMultiCollectio @@ -120,7 +120,7 @@ public class UpdateMultiCollectionHandler : IRequestHandler<UpdateMultiCollectio
if (await dbContext.SaveChangesAsync() > 0)
{
_searchTargets.SearchTargetsChanged();
// refresh all playouts that use this collection
foreach (int playoutId in await _mediaCollectionRepository.PlayoutIdsUsingMultiCollection(
request.MultiCollectionId))

2
ErsatzTV.Application/MediaCollections/Commands/UpdateSmartCollectionHandler.cs

@ -14,9 +14,9 @@ namespace ErsatzTV.Application.MediaCollections; @@ -14,9 +14,9 @@ namespace ErsatzTV.Application.MediaCollections;
public class UpdateSmartCollectionHandler : IRequestHandler<UpdateSmartCollection, Either<BaseError, Unit>>
{
private readonly ChannelWriter<IBackgroundServiceRequest> _channel;
private readonly ISearchTargets _searchTargets;
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly IMediaCollectionRepository _mediaCollectionRepository;
private readonly ISearchTargets _searchTargets;
public UpdateSmartCollectionHandler(
IDbContextFactory<TvContext> dbContextFactory,

7
ErsatzTV.Application/Playouts/Commands/BuildPlayoutHandler.cs

@ -17,13 +17,13 @@ namespace ErsatzTV.Application.Playouts; @@ -17,13 +17,13 @@ namespace ErsatzTV.Application.Playouts;
public class BuildPlayoutHandler : IRequestHandler<BuildPlayout, Either<BaseError, Unit>>
{
private readonly IBlockPlayoutBuilder _blockPlayoutBuilder;
private readonly IClient _client;
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly IEntityLocker _entityLocker;
private readonly IExternalJsonPlayoutBuilder _externalJsonPlayoutBuilder;
private readonly IFFmpegSegmenterService _ffmpegSegmenterService;
private readonly IPlayoutBuilder _playoutBuilder;
private readonly IBlockPlayoutBuilder _blockPlayoutBuilder;
private readonly IExternalJsonPlayoutBuilder _externalJsonPlayoutBuilder;
private readonly ChannelWriter<IBackgroundServiceRequest> _workerChannel;
public BuildPlayoutHandler(
@ -100,7 +100,8 @@ public class BuildPlayoutHandler : IRequestHandler<BuildPlayout, Either<BaseErro @@ -100,7 +100,8 @@ public class BuildPlayoutHandler : IRequestHandler<BuildPlayout, Either<BaseErro
foreach (string channelNumber in maybeChannelNumber)
{
string fileName = Path.Combine(FileSystemLayout.ChannelGuideCacheFolder, $"{channelNumber}.xml");
if (hasChanges || !File.Exists(fileName) || playout.ProgramSchedulePlayoutType is ProgramSchedulePlayoutType.ExternalJson)
if (hasChanges || !File.Exists(fileName) ||
playout.ProgramSchedulePlayoutType is ProgramSchedulePlayoutType.ExternalJson)
{
await _workerChannel.WriteAsync(new RefreshChannelData(channelNumber), cancellationToken);
}

4
ErsatzTV.Application/Playouts/Commands/CreateExternalJsonPlayoutHandler.cs

@ -14,9 +14,9 @@ namespace ErsatzTV.Application.Playouts; @@ -14,9 +14,9 @@ namespace ErsatzTV.Application.Playouts;
public class CreateExternalJsonPlayoutHandler
: IRequestHandler<CreateExternalJsonPlayout, Either<BaseError, CreatePlayoutResponse>>
{
private readonly ILocalFileSystem _localFileSystem;
private readonly ChannelWriter<IBackgroundServiceRequest> _channel;
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly ILocalFileSystem _localFileSystem;
public CreateExternalJsonPlayoutHandler(
ILocalFileSystem localFileSystem,
@ -27,7 +27,7 @@ public class CreateExternalJsonPlayoutHandler @@ -27,7 +27,7 @@ public class CreateExternalJsonPlayoutHandler
_channel = channel;
_dbContextFactory = dbContextFactory;
}
public async Task<Either<BaseError, CreatePlayoutResponse>> Handle(
CreateExternalJsonPlayout request,
CancellationToken cancellationToken)

4
ErsatzTV.Application/Playouts/Commands/CreateFloodPlayoutHandler.cs

@ -41,7 +41,9 @@ public class CreateFloodPlayoutHandler : IRequestHandler<CreateFloodPlayout, Eit @@ -41,7 +41,9 @@ public class CreateFloodPlayoutHandler : IRequestHandler<CreateFloodPlayout, Eit
return new CreatePlayoutResponse(playout.Id);
}
private static async Task<Validation<BaseError, Playout>> Validate(TvContext dbContext, CreateFloodPlayout request) =>
private static async Task<Validation<BaseError, Playout>> Validate(
TvContext dbContext,
CreateFloodPlayout request) =>
(await ValidateChannel(dbContext, request), await ValidateProgramSchedule(dbContext, request),
ValidatePlayoutType(request))
.Apply(

4
ErsatzTV.Application/Playouts/Commands/ReplacePlayoutAlternateScheduleItems.cs

@ -2,5 +2,5 @@ using ErsatzTV.Core; @@ -2,5 +2,5 @@ using ErsatzTV.Core;
namespace ErsatzTV.Application.Playouts;
public record ReplacePlayoutAlternateScheduleItems
(int PlayoutId, List<ReplacePlayoutAlternateSchedule> Items) : IRequest<Either<BaseError, Unit>>;
public record ReplacePlayoutAlternateScheduleItems(int PlayoutId, List<ReplacePlayoutAlternateSchedule> Items)
: IRequest<Either<BaseError, Unit>>;

8
ErsatzTV.Application/Playouts/Commands/UpdateExternalJsonPlayoutHandler.cs

@ -8,7 +8,9 @@ using Microsoft.EntityFrameworkCore; @@ -8,7 +8,9 @@ using Microsoft.EntityFrameworkCore;
namespace ErsatzTV.Application.Playouts;
public class UpdateExternalJsonPlayoutHandler : IRequestHandler<UpdateExternalJsonPlayout, Either<BaseError, PlayoutNameViewModel>>
public class
UpdateExternalJsonPlayoutHandler : IRequestHandler<UpdateExternalJsonPlayout,
Either<BaseError, PlayoutNameViewModel>>
{
private readonly IDbContextFactory<TvContext> _dbContextFactory;
private readonly ChannelWriter<IBackgroundServiceRequest> _workerChannel;
@ -52,7 +54,9 @@ public class UpdateExternalJsonPlayoutHandler : IRequestHandler<UpdateExternalJs @@ -52,7 +54,9 @@ public class UpdateExternalJsonPlayoutHandler : IRequestHandler<UpdateExternalJs
Optional(playout.DailyRebuildTime));
}
private static Task<Validation<BaseError, Playout>> Validate(TvContext dbContext, UpdateExternalJsonPlayout request) =>
private static Task<Validation<BaseError, Playout>> Validate(
TvContext dbContext,
UpdateExternalJsonPlayout request) =>
PlayoutMustExist(dbContext, request);
private static Task<Validation<BaseError, Playout>> PlayoutMustExist(

4
ErsatzTV.Application/Playouts/Commands/UpdatePlayout.cs

@ -2,5 +2,5 @@ @@ -2,5 +2,5 @@
namespace ErsatzTV.Application.Playouts;
public record UpdatePlayout
(int PlayoutId, Option<TimeSpan> DailyRebuildTime) : IRequest<Either<BaseError, PlayoutNameViewModel>>;
public record UpdatePlayout(int PlayoutId, Option<TimeSpan> DailyRebuildTime)
: IRequest<Either<BaseError, PlayoutNameViewModel>>;

4
ErsatzTV.Application/Playouts/Queries/GetFuturePlayoutItemsById.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
namespace ErsatzTV.Application.Playouts;
public record GetFuturePlayoutItemsById
(int PlayoutId, bool ShowFiller, int PageNum, int PageSize) : IRequest<PagedPlayoutItemsViewModel>;
public record GetFuturePlayoutItemsById(int PlayoutId, bool ShowFiller, int PageNum, int PageSize)
: IRequest<PagedPlayoutItemsViewModel>;

3
ErsatzTV.Application/Plex/Commands/UpdatePlexLibraryPreferences.cs

@ -2,7 +2,6 @@ @@ -2,7 +2,6 @@
namespace ErsatzTV.Application.Plex;
public record UpdatePlexLibraryPreferences
(List<PlexLibraryPreference> Preferences) : IRequest<Either<BaseError, Unit>>;
public record UpdatePlexLibraryPreferences(List<PlexLibraryPreference> Preferences) : IRequest<Either<BaseError, Unit>>;
public record PlexLibraryPreference(int Id, bool ShouldSyncItems);

2
ErsatzTV.Application/Plex/Commands/UpdatePlexLibraryPreferencesHandler.cs

@ -6,7 +6,7 @@ namespace ErsatzTV.Application.Plex; @@ -6,7 +6,7 @@ namespace ErsatzTV.Application.Plex;
public class
UpdatePlexLibraryPreferencesHandler : IRequestHandler<UpdatePlexLibraryPreferences,
Either<BaseError, Unit>>
Either<BaseError, Unit>>
{
private readonly IMediaSourceRepository _mediaSourceRepository;
private readonly ISearchIndex _searchIndex;

3
ErsatzTV.Application/Plex/Commands/UpdatePlexPathReplacements.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.Plex;
public record UpdatePlexPathReplacements
(
public record UpdatePlexPathReplacements(
int PlexMediaSourceId,
List<PlexPathReplacementItem> PathReplacements) : IRequest<Either<BaseError, Unit>>;

4
ErsatzTV.Application/Plex/Queries/GetPlexConnectionParameters.cs

@ -2,5 +2,5 @@ @@ -2,5 +2,5 @@
namespace ErsatzTV.Application.Plex;
public record GetPlexConnectionParameters
(int PlexMediaSourceId) : IRequest<Either<BaseError, PlexConnectionParametersViewModel>>;
public record GetPlexConnectionParameters(int PlexMediaSourceId)
: IRequest<Either<BaseError, PlexConnectionParametersViewModel>>;

3
ErsatzTV.Application/Plex/Queries/GetPlexPathReplacementsBySourceId.cs

@ -1,4 +1,3 @@ @@ -1,4 +1,3 @@
namespace ErsatzTV.Application.Plex;
public record GetPlexPathReplacementsBySourceId
(int PlexMediaSourceId) : IRequest<List<PlexPathReplacementViewModel>>;
public record GetPlexPathReplacementsBySourceId(int PlexMediaSourceId) : IRequest<List<PlexPathReplacementViewModel>>;

2
ErsatzTV.Application/ProgramSchedules/Commands/AddProgramScheduleItemHandler.cs

@ -29,7 +29,7 @@ public class AddProgramScheduleItemHandler : ProgramScheduleItemCommandBase, @@ -29,7 +29,7 @@ public class AddProgramScheduleItemHandler : ProgramScheduleItemCommandBase,
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, ProgramSchedule> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, ps => PersistItem(dbContext, request, ps));
return await validation.Apply(ps => PersistItem(dbContext, request, ps));
}
private async Task<ProgramScheduleItemViewModel> PersistItem(

4
ErsatzTV.Application/ProgramSchedules/Commands/CopyProgramSchedule.cs

@ -2,5 +2,5 @@ @@ -2,5 +2,5 @@
namespace ErsatzTV.Application.ProgramSchedules;
public record CopyProgramSchedule
(int ProgramScheduleId, string Name) : IRequest<Either<BaseError, ProgramScheduleViewModel>>;
public record CopyProgramSchedule(int ProgramScheduleId, string Name)
: IRequest<Either<BaseError, ProgramScheduleViewModel>>;

5
ErsatzTV.Application/ProgramSchedules/Commands/ReplaceProgramScheduleItems.cs

@ -32,6 +32,5 @@ public record ReplaceProgramScheduleItem( @@ -32,6 +32,5 @@ public record ReplaceProgramScheduleItem(
string PreferredSubtitleLanguageCode,
ChannelSubtitleMode? SubtitleMode) : IProgramScheduleItemRequest;
public record ReplaceProgramScheduleItems
(int ProgramScheduleId, List<ReplaceProgramScheduleItem> Items) : IRequest<
Either<BaseError, IEnumerable<ProgramScheduleItemViewModel>>>;
public record ReplaceProgramScheduleItems(int ProgramScheduleId, List<ReplaceProgramScheduleItem> Items) : IRequest<
Either<BaseError, IEnumerable<ProgramScheduleItemViewModel>>>;

3
ErsatzTV.Application/ProgramSchedules/Commands/UpdateProgramSchedule.cs

@ -2,8 +2,7 @@ @@ -2,8 +2,7 @@
namespace ErsatzTV.Application.ProgramSchedules;
public record UpdateProgramSchedule
(
public record UpdateProgramSchedule(
int ProgramScheduleId,
string Name,
bool KeepMultiPartEpisodesTogether,

2
ErsatzTV.Application/ProgramSchedules/Commands/UpdateProgramScheduleHandler.cs

@ -29,7 +29,7 @@ public class UpdateProgramScheduleHandler : @@ -29,7 +29,7 @@ public class UpdateProgramScheduleHandler :
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, ProgramSchedule> validation = await Validate(dbContext, request);
return await LanguageExtensions.Apply(validation, ps => ApplyUpdateRequest(dbContext, ps, request));
return await validation.Apply(ps => ApplyUpdateRequest(dbContext, ps, request));
}
private async Task<UpdateProgramScheduleResult> ApplyUpdateRequest(

8
ErsatzTV.Application/Scheduling/Commands/CreateBlockGroupHandler.cs

@ -8,13 +8,15 @@ namespace ErsatzTV.Application.Scheduling; @@ -8,13 +8,15 @@ namespace ErsatzTV.Application.Scheduling;
public class CreateBlockGroupHandler(IDbContextFactory<TvContext> dbContextFactory)
: IRequestHandler<CreateBlockGroup, Either<BaseError, BlockGroupViewModel>>
{
public async Task<Either<BaseError, BlockGroupViewModel>> Handle(CreateBlockGroup request, CancellationToken cancellationToken)
public async Task<Either<BaseError, BlockGroupViewModel>> Handle(
CreateBlockGroup request,
CancellationToken cancellationToken)
{
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, BlockGroup> validation = await Validate(request);
return await validation.Apply(profile => PersistBlockGroup(dbContext, profile));
}
private static async Task<BlockGroupViewModel> PersistBlockGroup(TvContext dbContext, BlockGroup blockGroup)
{
await dbContext.BlockGroups.AddAsync(blockGroup);
@ -24,7 +26,7 @@ public class CreateBlockGroupHandler(IDbContextFactory<TvContext> dbContextFacto @@ -24,7 +26,7 @@ public class CreateBlockGroupHandler(IDbContextFactory<TvContext> dbContextFacto
private static Task<Validation<BaseError, BlockGroup>> Validate(CreateBlockGroup request) =>
Task.FromResult(ValidateName(request).Map(name => new BlockGroup { Name = name, Blocks = [] }));
private static Validation<BaseError, string> ValidateName(CreateBlockGroup createBlockGroup) =>
createBlockGroup.NotEmpty(x => x.Name)
.Bind(_ => createBlockGroup.NotLongerThan(50)(x => x.Name));

39
ErsatzTV.Application/Scheduling/Commands/CreateBlockHandler.cs

@ -13,7 +13,7 @@ public class CreateBlockHandler(IDbContextFactory<TvContext> dbContextFactory) @@ -13,7 +13,7 @@ public class CreateBlockHandler(IDbContextFactory<TvContext> dbContextFactory)
CancellationToken cancellationToken)
{
await using TvContext dbContext = await dbContextFactory.CreateDbContextAsync(cancellationToken);
Validation<BaseError, Block> validation = await Validate(request);
Validation<BaseError, Block> validation = await Validate(dbContext, request);
return await validation.Apply(profile => PersistBlock(dbContext, profile));
}
@ -24,17 +24,30 @@ public class CreateBlockHandler(IDbContextFactory<TvContext> dbContextFactory) @@ -24,17 +24,30 @@ public class CreateBlockHandler(IDbContextFactory<TvContext> dbContextFactory)
return Mapper.ProjectToViewModel(block);
}
private static Task<Validation<BaseError, Block>> Validate(CreateBlock request) =>
Task.FromResult(
ValidateName(request).Map(
name => new Block
{
BlockGroupId = request.BlockGroupId,
Name = name,
Minutes = 30
}));
private static async Task<Validation<BaseError, Block>> Validate(TvContext dbContext, CreateBlock request) =>
await ValidateBlockName(dbContext, request).MapT(
name => new Block
{
BlockGroupId = request.BlockGroupId,
Name = name,
Minutes = 30
});
private static Validation<BaseError, string> ValidateName(CreateBlock createBlock) =>
createBlock.NotEmpty(x => x.Name)
.Bind(_ => createBlock.NotLongerThan(50)(x => x.Name));
private static async Task<Validation<BaseError, string>> ValidateBlockName(
TvContext dbContext,
CreateBlock request)
{
if (request.Name.Length > 50)
{
return BaseError.New($"Block name \"{request.Name}\" is invalid");
}
Option<Block> maybeExisting = await dbContext.Blocks
.FirstOrDefaultAsync(r => r.BlockGroupId == request.BlockGroupId && r.Name == request.Name)
.Map(Optional);
return maybeExisting.IsSome
? BaseError.New($"A block named \"{request.Name}\" already exists in that block group")
: request.Name;
}
}

2
ErsatzTV.Application/Scheduling/Commands/EraseBlockPlayoutItemsHandler.cs

@ -40,7 +40,7 @@ public class EraseBlockPlayoutItemsHandler(IDbContextFactory<TvContext> dbContex @@ -40,7 +40,7 @@ public class EraseBlockPlayoutItemsHandler(IDbContextFactory<TvContext> dbContex
// save history changes
await dbContext.SaveChangesAsync(cancellationToken);
// delete all playout items
await dbContext.Database.ExecuteSqlAsync(
$"DELETE FROM PlayoutItem WHERE PlayoutId = {playout.Id}",

6
ErsatzTV.Application/Scheduling/Commands/ReplaceBlockItemsHandler.cs

@ -28,7 +28,7 @@ public class ReplaceBlockItemsHandler(IDbContextFactory<TvContext> dbContextFact @@ -28,7 +28,7 @@ public class ReplaceBlockItemsHandler(IDbContextFactory<TvContext> dbContextFact
block.Minutes = request.Minutes;
block.StopScheduling = request.StopScheduling;
block.DateUpdated = DateTime.UtcNow;
dbContext.RemoveRange(block.Items);
block.Items = request.Items.Map(i => BuildItem(block, i.Index, i)).ToList();
@ -67,7 +67,7 @@ public class ReplaceBlockItemsHandler(IDbContextFactory<TvContext> dbContextFact @@ -67,7 +67,7 @@ public class ReplaceBlockItemsHandler(IDbContextFactory<TvContext> dbContextFact
.Include(b => b.Items)
.SelectOneAsync(b => b.Id, b => b.Id == blockId)
.Map(o => o.ToValidation<BaseError>("[BlockId] does not exist."));
private static Validation<BaseError, Block> MinutesMustBeValid(ReplaceBlockItems request, Block block) =>
Optional(block)
.Filter(_ => request.Minutes > 0 && request.Minutes % 15 == 0 && request.Minutes <= 24 * 60)
@ -75,7 +75,7 @@ public class ReplaceBlockItemsHandler(IDbContextFactory<TvContext> dbContextFact @@ -75,7 +75,7 @@ public class ReplaceBlockItemsHandler(IDbContextFactory<TvContext> dbContextFact
private static Validation<BaseError, Block> CollectionTypesMustBeValid(ReplaceBlockItems request, Block block) =>
request.Items.Map(item => CollectionTypeMustBeValid(item, block)).Sequence().Map(_ => block);
private static Validation<BaseError, Block> CollectionTypeMustBeValid(ReplaceBlockItem item, Block block)
{
switch (item.CollectionType)

4
ErsatzTV.Application/Scheduling/Commands/ReplacePlayoutTemplateItemsHandler.cs

@ -42,7 +42,7 @@ public class ReplacePlayoutTemplateItemsHandler( @@ -42,7 +42,7 @@ public class ReplacePlayoutTemplateItemsHandler(
playout.Templates.Remove(remove);
}
var now = DateTime.UtcNow;
DateTime now = DateTime.UtcNow;
foreach (ReplacePlayoutTemplate add in toAdd)
{
@ -71,7 +71,7 @@ public class ReplacePlayoutTemplateItemsHandler( @@ -71,7 +71,7 @@ public class ReplacePlayoutTemplateItemsHandler(
ex.DateUpdated = now;
}
}
await dbContext.SaveChangesAsync(cancellationToken);
}

3
ErsatzTV.Application/Scheduling/Queries/GetTemplateItemsHandler.cs

@ -3,7 +3,8 @@ using Microsoft.EntityFrameworkCore; @@ -3,7 +3,8 @@ using Microsoft.EntityFrameworkCore;
namespace ErsatzTV.Application.Scheduling;
public class GetTemplateItemsHandler(IDbContextFactory<TvContext> dbContextFactory) : IRequestHandler<GetTemplateItems, List<TemplateItemViewModel>>
public class GetTemplateItemsHandler(IDbContextFactory<TvContext> dbContextFactory)
: IRequestHandler<GetTemplateItems, List<TemplateItemViewModel>>
{
public async Task<List<TemplateItemViewModel>> Handle(GetTemplateItems request, CancellationToken cancellationToken)
{

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save