Browse Source

fix other video artwork in xmltv

pull/2777/head
Jason Dove 7 months ago
parent
commit
caedd8370b
No known key found for this signature in database
  1. 2
      CHANGELOG.md
  2. 4
      ErsatzTV.Application/Channels/Commands/RefreshChannelDataHandler.cs
  3. 1
      ErsatzTV.Core/Interfaces/Repositories/IOtherVideoRepository.cs
  4. 11
      ErsatzTV.Infrastructure/Data/Repositories/OtherVideoRepository.cs
  5. 15
      ErsatzTV.Scanner/Core/Metadata/OtherVideoFolderScanner.cs
  6. 6
      ErsatzTV/Resources/Templates/_otherVideo.sbntxt

2
CHANGELOG.md

@ -24,6 +24,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). @@ -24,6 +24,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- MySql: fix searching for shows and seasons in schedule items editor
- Fix 500 errors when serving XMLTV due to concurrent file reads and writes
- Fix playback of AC3 audio when targeting stereo output and input layout changes mid-stream
- Use other video artwork in XMLTV template
- Remove artwork from other videos when artwork has been removed from disk
## [26.1.1] - 2026-01-08
### Fixed

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

@ -883,6 +883,8 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -883,6 +883,8 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
metadata.Genres ??= [];
metadata.Guids ??= [];
string artworkPath = GetPrioritizedArtworkPath(metadata);
var data = new
{
ProgrammeStart = start,
@ -897,6 +899,8 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData> @@ -897,6 +899,8 @@ public class RefreshChannelDataHandler : IRequestHandler<RefreshChannelData>
OtherVideoPlot = metadata.Plot,
OtherVideoHasYear = metadata.Year.HasValue,
OtherVideoYear = metadata.Year,
OtherVideoHasArtwork = !string.IsNullOrWhiteSpace(artworkPath),
OtherVideoArtworkUrl = artworkPath,
OtherVideoGenres = metadata.Genres.Map(g => g.Name).OrderBy(n => n),
OtherVideoHasContentRating = !string.IsNullOrWhiteSpace(metadata.ContentRating),
OtherVideoContentRating = metadata.ContentRating

1
ErsatzTV.Core/Interfaces/Repositories/IOtherVideoRepository.cs

@ -19,4 +19,5 @@ public interface IOtherVideoRepository @@ -19,4 +19,5 @@ public interface IOtherVideoRepository
Task<bool> AddActor(OtherVideoMetadata metadata, Actor actor);
Task<bool> AddDirector(OtherVideoMetadata metadata, Director director);
Task<bool> AddWriter(OtherVideoMetadata metadata, Writer writer);
Task<bool> RemoveArtwork(OtherVideoMetadata metadata, ArtworkKind artworkKind);
}

11
ErsatzTV.Infrastructure/Data/Repositories/OtherVideoRepository.cs

@ -46,6 +46,8 @@ public class OtherVideoRepository : IOtherVideoRepository @@ -46,6 +46,8 @@ public class OtherVideoRepository : IOtherVideoRepository
.ThenInclude(ovm => ovm.Directors)
.Include(i => i.OtherVideoMetadata)
.ThenInclude(ovm => ovm.Writers)
.Include(i => i.OtherVideoMetadata)
.ThenInclude(ovm => ovm.Artwork)
.Include(ov => ov.LibraryPath)
.ThenInclude(lp => lp.Library)
.Include(ov => ov.MediaVersions)
@ -173,6 +175,15 @@ public class OtherVideoRepository : IOtherVideoRepository @@ -173,6 +175,15 @@ public class OtherVideoRepository : IOtherVideoRepository
new { writer.Name, MetadataId = metadata.Id }).Map(result => result > 0);
}
public async Task<bool> RemoveArtwork(OtherVideoMetadata metadata, ArtworkKind artworkKind)
{
await using TvContext dbContext = await _dbContextFactory.CreateDbContextAsync();
var ids = metadata.Artwork.Where(a => a.ArtworkKind == artworkKind).Select(a => a.Id).ToHashSet();
return await dbContext.Artwork
.Where(a => ids.Contains(a.Id))
.ExecuteDeleteAsync() > 0;
}
private async Task<Either<BaseError, MediaItemScanResult<OtherVideo>>> AddOtherVideo(
TvContext dbContext,
int libraryPathId,

15
ErsatzTV.Scanner/Core/Metadata/OtherVideoFolderScanner.cs

@ -359,11 +359,18 @@ public class OtherVideoFolderScanner : LocalFolderScanner, IOtherVideoFolderScan @@ -359,11 +359,18 @@ public class OtherVideoFolderScanner : LocalFolderScanner, IOtherVideoFolderScan
{
OtherVideo otherVideo = result.Item;
Option<string> maybeThumbnail = LocateThumbnail(otherVideo);
foreach (string thumbnailFile in maybeThumbnail)
foreach (var metadata in otherVideo.OtherVideoMetadata.HeadOrNone())
{
OtherVideoMetadata metadata = otherVideo.OtherVideoMetadata.Head();
await RefreshArtwork(thumbnailFile, metadata, ArtworkKind.Thumbnail, None, None, cancellationToken);
Option<string> maybeThumbnail = LocateThumbnail(otherVideo);
foreach (string thumbnailFile in maybeThumbnail)
{
await RefreshArtwork(thumbnailFile, metadata, ArtworkKind.Thumbnail, None, None, cancellationToken);
}
if (maybeThumbnail.IsNone && metadata.Artwork.Any(a => a.ArtworkKind is ArtworkKind.Thumbnail))
{
await _otherVideoRepository.RemoveArtwork(metadata, ArtworkKind.Thumbnail);
}
}
return result;

6
ErsatzTV/Resources/Templates/_otherVideo.sbntxt

@ -13,6 +13,8 @@ Available values: @@ -13,6 +13,8 @@ Available values:
- other_video_plot
- other_video_has_year
- other_video_year
- other_video_has_artwork
- other_video_artwork_url
- other_video_genres
- other_video_has_content_rating
- other_video_content_rating
@ -35,8 +37,8 @@ The resulting XML will be minified by ErsatzTV - so feel free to keep things nic @@ -35,8 +37,8 @@ The resulting XML will be minified by ErsatzTV - so feel free to keep things nic
{{ for genre in other_video_genres }}
<category lang="en">{{ genre }}</category>
{{ end }}
{{ if movie_has_artwork }}
<icon src="{{ movie_artwork_url }}" />
{{ if other_video_has_artwork }}
<icon src="{{ other_video_artwork_url }}" />
{{ end }}
{{ end }}
{{ if other_video_has_content_rating }}

Loading…
Cancel
Save